Java类型信息

RTTI——运行时类型信息(Run-Time Type Information),通过运行时类型信息程序能够使用基类指针或引用来检查这些指针或引用所指的对象的实际派生类型。

       RTTI提供了以下两个非常有用的操作符:

(1)typeId操作符,返回指针和引用所指的实际类型。

(2)dynamicCast操作符,将基类类型的指针或引用安全地转换为派生类型的指针或引用。

代码示例:

 1 public class Test1 { 
 2    public static void main(String[] args) {
 3      
 4       // 把Square,Triangle对象放入List时会向上转型为Shape
 5       List<Shape> shapelist = Arrays.asList(new Shape(), new Square(), new Triangle());
 6 
 7       // 多态机制确保:Shape对象执行什么样的代码由引用所指向的具体对象确定的
 9       for (Shape shape : shapelist) {
10         shape.draw();
11       }
12    }
13

运行结果:

我是基类Shape的draw()方法!

我是子类Square的draw()方法!

我是子类Triangle的draw()方法!

总结:使用RTTI,可以查询某个Shape引用所指向的对象的确切类型,然后选择或者剔除个例。注意:RTTI允许通过匿名基类的引用来发现类信息,但是要注意能够使用多态机制实现的话,优先选用多态,否则在代码开发以及维护过程中损失了很多多态机制的重要价值,必要的时候才会选用RTTI。

RTTI在java中的工作原理:

    在java中有一种称为Class对象的特殊对象,其包含与类有关的信息,RTTI即是通过Class对象来执行的,每当编写完了一个新类,然后进行编译,java虚拟机的“类加载器”子系统在运行程序时,在程序创建第一个对类的静态成员的引用时,就会加载这个类,(说明:即使在构造器前没有static关键字修饰,类的构造器也是类的静态方法,因此使用new操作符创建类对象时也可以看做是对类的静态成员的引用)。

获得Class对象引用的方法:

1. 具体对象.getClass(): 持有此类型的对象时,可以使用此方法

2. Class.forName():不需要为了获得Class引用而持有该类型的对象。但是需要注意:要放到try-catch子句中,因为如果找不到这个类,会抛出ClassNotFoundException。获得对类的引用的同时进行初始化。

3. 类字面常量。在编译期就会受到检查,无需try-catch。使用类字面常量来获得对类的引用不会引发初始化,初始化实现了“惰性”,即延迟到了对静态方法(构造器隐式地是静态的)或者非常数静态域进行首次引用时才执行。

package classInformation;
class Candy {
    static { System.out.println("Loading Candy"); }
}
class Gum {
    static { System.out.println("Loading Gum"); } 
}
class Cookie {
    static { System.out.println("Loading Cookie"); }
}
public class SweetShop {
    public static void main(String[] args) {
        // 第一种方式:
        Candy c= new Candy();
        System.out.println("创建的对象Candy的信息:"+c.getClass());
        // 第二种方式:
        try {
            Class.forName("classInformation.Gum"); 
// Class.forName("完整路径包名.类名称")
} catch(ClassNotFoundException e) {
System.out.println("Couldn't find Gum");
}
// 第三种方式:
Class cc = Cookie.class;
System.out.println(Cookie.class);
    }
}

 程序运行结果:

Loading Candy

创建的对象Candy的信息:class classInformation.Candy

Loading Gum

class classInformation.Cookie

类型转换:

1. 进行向下转型,需要显式的转型操作;

2. 进行向上转向,不需要显式的转型操作;

3. 关键字instanceof,可以用提问的方式使用它,去判断某个对象到底是那个特性类型的实例;

反射:运行时的类信息

    Java通过javaBeans提供了基于构建的编程框架,通过“远程方法调用(remote method invocation,RMI)”提供跨网络的远程平台上创建和运行对象的方法,Class类和java.lang.reflection类库一起对反射的概念进行了支撑,通过反射和一个未知类型的对象打交道,首先JVM检查该对象属于哪个类,通过类方法提取器获得该类型的可用方法。

原文地址:https://www.cnblogs.com/fengyouyou/p/7760822.html