【Java基础】RTTI和Java反射机制

一、RTTI

RTTI(Run-Time Type Information)指的是运行时类型信息,这让你可以在程序运行时发现和使用类型信息。Java中让我们在运行时识别对象和类的信息的方式主要有两种。

  • 传统的"RTTI",假定我们在编译的时候就已经知道了所有的类型信息。
  • “反射”机制,允许我们在运行时候发现和使用类型信息。

二、RTTI使用背景

假设和我们定义了Shape, Square, Circle, Triangle.等类,并且后三者继承自Shape。具体使用某个类的时候使用多态调用

Shape sp = new Circle();
sp = new Triangle();
sp = new Square();
一个图形只要增加一个类,而具体调用的地方则不用修改。
现在有一个需求:把所有Triangle设置为红色。在只暴露了Shape的引用sp的情况下获得sp具体的类型信息。这是就是RTTI的一个具体的需求,即在运行多态的好处是动态绑定调用方法,只有在执行的时候才知道sp绑定的是哪个具体子类的方法。这种方法的好处是代码跟容易维护和扩展,因为要增加时候发现和使用类型信息。
 
   
abstract class Shape{
    void draw(){
        System.out.println(this+".draw()");
    }

    abstract public String toString();
}

class  Circle extends Shape{

    @Override
    public String toString() {
        return "Circle";
    }
}

class  Square extends Shape{
    static {
        System.out.println("loading square......");
    }
    @Override
    public String toString() {
        return "Square";
    }
}

class  Triangle extends Shape{

    @Override
    public String toString() {
        return "Triangle";
    }
}

public class RTTI {
    public static void main(String[] args) {
        Shape sp = new Triangle();
       
    }
}

三、RTTI的核心

Java中支持RTTI工作的核心即是Class对象,类型信息是由Class对象所维护的。类是程序的一部分,每一个类都有一个Class对象(保存在.class) 文件之中,在使用一个类生成对象时,java虚拟机会使用类加载器加载Class对象(查找Class文件)。所以获取RTTI就是获取类的Class对象的引用。
常用的获取RTTI的方法
  • 知道类的名称
 Class p = Class.forName("Inn");//有异常抛出
 Class p = Inn.class;//字面常量
  • 知道类对象的引用
Class p = sp.getClass();

四、反射:运行时的类信息

在使用传统的RTTI时候有个限制,就是类型在编译时候必须已知,这样传统的RTTI才会识别。即在编译时,编译器必须知道所有要通过RTTI处理的类。
但是现在还有一个需求,假设你获得了一个网络程序的引用,你并不能在编译期间获得对象所属的类。在分布式环境中比较常见。
Java中支持反射机制的是Class类和java.lang.reflect类库【Field、Method、Constructor】
通过运行时获取Class对象,再通过Field、Method、Constructor获取未知类的属性、普通方法、构造器,从而对这个对象的类进行使用。
简单来说 反射是和未知类型的对象打交道,使用未知对象提供的方法以及获取其属性。
传统RTTI和反射机制的区别是
  • 对RTTI来说,在编译期间打开和检查.class文件
  • 对反射来说,在运行期间打开和检查.class文件【本地获取或者网络获取】

你可能感兴趣的:(Java基础,Java,编程思想)