從頭認識java-12.1 為什麼需要RTTI(Run-Time Type Identification)?
這一章節我們來討論一下為什麼需要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 birdClass = (Class) 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方法。