RTTI可以帮助我们在运行时识别对象和类的信息。
一般传统的RTTI有三种实现方式:
1. 向上转型或向下转型(upcasting and downcasting),在java中,向下转型(父类转成子类)需要强制类型转换
2. Class对象(用了Class对象,不代表就是反射,如果只是用Class对象cast成指定的类,那就还是传统的RTTI)
3. instanceof或isInstance()
通过Class对象实现RTTI
interface HasBatteries{} interface Waterproof{} interface Shoots{} class Toy{ Toy() {} Toy(int i) {} } class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots { public FancyToy() { super(1); } } public class ToyTest { public static void printInfo(Class c) { System.out.println("Class name: " + c.getName() + " " + "is interface: " + c.isInterface() + " " + "Simple name: " + c.getSimpleName() + " " + "Cannonical name: " + c.getCanonicalName() ); } public static void main(String[] args) { Class c = null; try { c = Class.forName("FancyToy"); //通过Class提供的forName方法得到FancyToy的Class对象 } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("FancyToy类的基本信息:"); printInfo(c); System.out.println("FancyToy实现的接口的信息:"); for (Class interf : c.getInterfaces()) { printInfo(interf); } Class up = c.getSuperclass(); System.out.println("FancyToy的父类的信息:"); printInfo(up); Toy toy = null; try { toy = (Toy)up.newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } printInfo(Toy.class); //通过类字面值常量获得Class对象 } } 输出: FancyToy类的基本信息: Class name: FancyToy is interface: false Simple name: FancyToy Cannonical name: FancyToy FancyToy实现的接口的信息: Class name: HasBatteries is interface: true Simple name: HasBatteries Cannonical name: HasBatteries Class name: Waterproof is interface: true Simple name: Waterproof Cannonical name: Waterproof Class name: Shoots is interface: true Simple name: Shoots Cannonical name: Shoots FancyToy的父类的信息: Class name: Toy is interface: false Simple name: Toy Cannonical name: Toy Class name: Toy is interface: false Simple name: Toy Cannonical name: Toy
Class还有泛化的,例如: Class<? extends Base>表示所有继承自Base的类的Class对象。
instanceof /Class.isInstance
class Base{} class Derived extends Base{} public class ToyTest { public static void test(Object x) { /* * instanceof /Class.isInstance 表示左边的是右边的这个类吗?或者是右边这个类的派生类吗? * == 或者 equal 比较的是确切的类型 */ System.out.println("Testing x of type : " + x.getClass()); System.out.println("x instance of Base : " + (x instanceof Base)); System.out.println("x instanceof Derived : " + (x instanceof Derived)); System.out.println("Base.isInstance : " + Base.class.isInstance(x)); System.out.println("Derived.isInstance : " + Derived.class.isInstance(x)); System.out.println("x.getClass() == Base.class" + (x.getClass() == Base.class)); System.out.println("x.getClass() == Derived.class" + (x.getClass() == Derived.class)); System.out.println("x.getClass().equals(Base.class)" + (x.getClass().equals(Base.class))); System.out.println("x.getClass().equals(Derived.class)" + (x.getClass().equals(Derived.class))); } public static void main(String[] args) { test(new Base()); test(new Derived()); } }
参考: 《Java编程思想》14章