Java 类型信息(RTTI与反射)

类型信息

Java通过两种方式在运行时识别对象和类的信息。一种是“传统的RTTI (Run-Time Type Identification)”,它假定我们在编译时就已经知道了所有的类型,另一种是“反射”机制,它允许我们在运行时发现和使用类的信息。

1. RTTI

① RTTI是什么?它有什么作用?

RTTI (Run-Time Type Identification),即运行时类型识别。通俗一些就是通过RTTI,我们可以在程序运行的时候去识别出一个对象或者一个类的具体的类型信息并可以去获取并运用这些信息。(当程序编译时会为每个类产生一个同名的.class文件,同时也会在该文件中保存一个与该类对应的Class对象。在程序运行时,RTTI便是根据Class对象来识别具体类型的)。

举几个例子:

  1. 当我们使用多态时,希望通过父类来执行具体类型(可能是某个子类)的方法,而通过父类怎么就知道它要执行哪个具体类型中的方法呢,这个时候RTTI就派上用场了,在运行时来辨别出该对象的具体类型,从而执行该具体类型中对应的方法。这个例子是RTTI使用的一种方式。
  2. 在对一个对象进行类型强转的时候,我们常常需要在强转之前判断一下,该对象是否属于将要强转的那个类型,如果属于的话,我们才让它强转。否则就有可能在运行的时候抛出异常。通常我们通过 instanceof 这个关键字可以在程序运行时来判断某个对象的类型,使用 instanceof 也是一种RTTI使用的一种方式。

2. 反射

①. 什么是反射?

反射也是在运行时识别对象和类的信息的一种方式,但反射是在程序运行的时候才动态的打开.class文件,并根据.class文件来识别和获取类型信息。归根结底反射和RTTI的真正区别地方在于,RTTI在编译阶段就已经打开并检查了.class文件,所以在运行阶段可以直接通过.class文件中加载Class对象并通过Class对象识别并获取一个对象具体的类型信息。而反射在编译阶段不可获取.class文件,需要在运行时打开和检查.class文件。

②. 反射的用途

既然RTTI和反射都可以在运行时获取到对象和类的类型信息,而且反射又这么麻烦,那它存在的意义是什么呢?

反射由于是在运行时才决定打开对应类的.class文件,便说明反射可以动态的使用某个类。

举个例子:

假设我们的程序部署到远端的服务器上供用户使用,并给用户提供了一个接口,用户通过该接口可以发送一段字符串去让程序去创建一个对应的类的对象,例如发送”Person“,服务端便创建一个Person对象。这样在程序中只需要一句代码:Class.forName("一段字符串") 便可以获取Person类的Class对象,通过Class对象便可以创建一个Person实例。

 这便是使用反射的一个例子。通过RTTI我们不可能实现这种功能(或者说我们肯定不愿意实现),因为RTTI始终是通过已经编写好的静态代码来实现。除非你愿意使用很多的 if 或者 switch 语句一个一个把每个类都 instanceof 一下。

一些细节:

1.在Java中,所有的类型转换都是在运行时进行正确性检查的。即RTTI的含义:在运行时,识别一个对象的类型。

2.Java使用Class对象来执行其RTTI,每一个类都有一个Class对象,每当编写并编译了一个新类,就会产生一个Class对象。

3.每当程序创建第一个对类的静态成员的引用时,就会加载这个类,所以证明了构造器也是类的静态方法。

4.一旦某个类的Class对象被载入内存,它就用来创建这个类的所有对象,Class对象仅在需要的时候才被加载。

5.对于基本数据类型的包装器类,还有一个标准字段TYPE,该字段是一个引用,指向对应基本数据类型的Class对象。

6.使用 “类名.class ” 来创建Class对象的引用时,不会自动地初始化该Class对象。

7.如果一个static final值是“编译期常量”,那么这个值不需要对它的类初始化就可以被读取。若一个static域不是final,那么对它访问时,总是要求在它被读取前,要先进行链接(为这个域分配空间)和初始化(初始化该存储空间)。

8.Class引用表示的就是它所指向的对象的确切类型,而该对象便是Class类的一个对象。

9.RTTI和反射之间真正的区别只在于,对于RTTI来说,编译器在编译时打开和检查.class文件。(换句话说,我们可以用“普通“的方式调用对象的所有方法)而对于反射机制,.class文件在编译时是不可获取的,所以是在运行时打开和检查.class文件。

10.Java中 null 除了在你试图用它执行任何操作来产生NullPointerException之外,它自己没有其他任何行为。所以可以引入空对象,该对象可以接受传递给它的所代表的对象的信息,但是将返回结果表示为实际上并不存在任何”真实“对象的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值