簡介
運行時類型信息可以在程序運行時發現和適應類型信息,使你從只能在編譯期執行面向類型的操作的禁錮中解脫出來。
java是如何讓我們在運行時識別對象和類型信息的呢?兩種方式:
- 傳統的“RTTI”,他假定我們在編譯時已經知道了所有的類型
- 反射,允許在運行時發現和使用類的信息
總結:反射是RTTI發展產生的概念和技術,多態是隱式地利用RTTI,反射則是顯式地使用RTTI。
1.RTTI
RTTI(Run-Time Type Identification),通過運行時類型信息程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實際派生類型。這個概念是來自C++的。
2.Class< T >類
每編譯了一個新類就會產生一個Class對象(更恰當地說,是被保存在一個同名的.class文件中),jvm使用“類加載器”來生成這個Class類的對象,這個類的Class對象會被放入內存,這個類的Class對象用來創建這個類的所有對象。關於類加載器的運行和加載順序本文先不做詳細描述。
java.lang.Class< T >
/**
* Instances of the class {@code Class} represent classes and
* interfaces in a running Java application. An enum is a kind of
* class and an annotation is a kind of interface. Every array also
* belongs to a class that is reflected as a {@code Class} object
* that is shared by all arrays with the same element type and number
* of dimensions. The primitive Java types ({@code boolean},
* {@code byte}, {@code char}, {@code short},
* {@code int}, {@code long}, {@code float}, and
* {@code double}), and the keyword {@code void} are also
* represented as {@code Class} objects.
*
*
{@code Class} has no public constructor. Instead {@code Class}
* objects are constructed automatically by the Java Virtual Machine as classes
* are loaded and by calls to the {@code defineClass} method in the class
* loader.
在正在運行的java程序中class的實例代表 類 和 接口。enum是類的一種,annotation是接口的一種。數組也是一種類。基礎java類型也是一個類對象({@code boolean},{@code byte}, {@code char}, {@code short}, {@code int}, {@code long}, {@code float}, and {@code double}),關鍵字{@code void}也是類對象。
Class類沒有公開的構造函數,是有jvm自動調用類加載器中的 {@code defineClass}方法構造的。
Class描述的是類的信息
1.如何獲取一個類的Class
- 類名.class
- Class.forName(全限定名)
- object.getClass()
Class class1=Reflect.class;
System.out.println(class1);//class com.fcc.jdk8api.core.reflect.Reflect
Class class2=new Reflect().getClass();
System.out.println(class2);//class com.fcc.jdk8api.core.reflect.Reflect
Class class3=Class.forName("java.lang.Class");//class java.lang.Class
System.out.println(class3);
System.out.println(class2.getName());//com.fcc.jdk8api.core.reflect.Reflect
System.out.println(class1==class2);//true
- ClassLoader.getSystemClassLoader().loadClass(“com.my.test.Hello”)
instanceof與Class的等價性
public static void test(){
Apple apple=new Apple();
System.out.println(Apple.class==apple.getClass());//true
System.out.println(Apple.class.equals(apple.getClass()));//true
System.out.println(apple instanceof Apple);//true
System.out.println(Apple.class.isInstance(apple));//true
System.out.println(apple.getClass().isInstance(apple));//true
}