运行时识别类型信息

      获取类型信息的必要性:运行时类型信息可以使程序员只能从编译期执行面向对象操作的禁锢中释放出来,使得可以在运行时发现和使用类型信息。主要两种方式:

1、RTTI     2、反射机制

 一、RTTI

     多态是面向对象编程的一个重要思想,我们面向接口(或者可以是基类)编程,然后基类中的方法会动态绑定到衍生类,这样只需要面对接口编程,便可以产生运行时的多态,大大简化了程序员的工作量。但是如果我们需要对特定的对象进行操作,比如我们有一个基类Shape,子类有Circle,Square,Triangle,基类中有一个方法rotate,需要对这些形状进行旋转,但圆旋转是没有意义的,所以我们需要在运行时判断该类是否是Circle的实例,来由我们做特殊的处理(过滤),这就需要RTTI。

    RTTI是通过创造Class对象的引用来实现的,有以下三种形式:

    1、传统的类型转换  如 (Shape)

    2、创造Class对象的引用,包括两种方法

    (1)Class.forName(): 这里涉及到了类的加载机制,即加载时会产生一个唯一的class对象,当第一次调用类的静态方法、静态域、静态块等等都会导致类的初始化。如果创造一个类的引用如 Class.forName(xxx.class) ,也会初始化该类,说明构造器也被视作类的静态方法。

    (2)类字面常量 :使用方法Class clazz = Test.class;好处是直接在编译时就会受到检查,无需置于try语句块中,而且根除了对forName()方法的调用,更高效。

      当使用.class来创建对象的引用时,实际过程有三步:加载 -> 链接 -> 初始化

      其中加载过程就是使用字节码,创建一个class对象;链接就是为静态域分配存储空间;初始化被延迟到了对静态方法的第一次调用(构造器隐式地是静态方法),或者是非常数静态域的第一次引用(因为常数静态域在类链接过程中就已经分配了内存,可以直接引用,必须为static final ,但static final也不能保证就是常数静态域,例如static final new Random().nextInt(); )。

      当使用Class引用时,Class<?>其实是优于Class的,因为这样会表示你就是故意选择一个非具体的版本,而非是忘掉了加上Class的类型。而且给Class加入泛型语法就会在编译期执行类型检查,使得错误可以较早发现。

       以及可以使用Class<? extends XXX> Class<? super XXX>。

    3、instanceof     /  isInstance()

二、反射

      但是RTTI有限制,必须是编译时编译器就已经知道所有的类型信息。而我们从网络或者磁盘中反序列化拿到的对象是没法从本地拿到它的 .class 文件的,但是原理是一样的。反射机制并没有多么高大上,无非RTTI是编译时编译器打开和检查.class文件,而反射是从本地或者是网络中在运行时打开和检查.class文件而已。

      Java.lang.reflect包提供了一系列如getFields(),getMethods(),getConstructors()

      一般编写也用不到反射机制,主要应用在对象序列化和JavaBean。

接下来,讲述关于动态代理的概念:

     代理是设计模式之一,



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值