这一章节我们来讨论一下为什么需要RTTI(Run-Time Type Identification)。
答案:RTTI维护类型的信息,为多态机制的实现提供基础。
1.怎么为多态的实现提供基础?
多态,主要就是通过向上转型,然后通过泛化来父类引用子类对象。
例如:
package com.ray.ch12;public class Test {public static void main(String[] args) {Person man = new Man();man.say();}
}class Person {public void say() {System.out.println("i am a person");}
}class Man extends Person {@Overridepublic void say() {System.out.println("i am a man");}
}
输出:
i am a man
通过继承,我们Man覆盖say方法,但是我们在new的时候写的类型是Person,通过RTTI它知道了需要调用Man的say方法,所以才有上面的输出。
我们举例来说明上面的描述:
package com.ray.ch12;public class Test {public static void main(String[] args) {Person person = new Person();System.out.println(person.getClass().getName());Person man = new Man();System.out.println(man.getClass().getName());}
}class Person {
}class Man extends Person {
}
输出:
com.ray.ch12.Person
com.ray.ch12.Man
我们通过getClass的getName方法,得到这个变量具体指向哪个类new出来的对象,虽然大家new的时候都是创建Person类型的对象,但是通过输出看见,其实上面两个变量是指向不同类生成的对象的,因此,对于第一段代码里面为什么能够输出“i am a man”,就是因为通过RTTI编译器知道调用哪个对象的方法。
2.RTTI提供一些什么信息?
关于这一点我们可以查看api里面Class这一个类的一些方法,它里面有详细描述。
我们下面将举一个比较常用的方法:forName
我们下面在同一个包里面建立两个类:
Bird:
package com.ray.ch12;public class Bird {
}
Test:
package com.ray.ch12;public class Test {@SuppressWarnings("unchecked")public static void main(String[] args) {try {Class<Bird> birdClass = (Class<Bird>) Class.forName("com.ray.ch12.Bird");Bird bird = (Bird) birdClass.newInstance();System.out.println(bird.getClass().getName());} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}
输出:
com.ray.ch12.Bird
RTTI还给我提供了丰富的类型信息,在运行当中我们可以适当的运用。
总结:这一章章节介绍了为什么需要RTTI,以及介绍了我们比较常用的forName方法。
这一章节就到这里,谢谢。
-----------------------------------
目录