java--反射(一)
一、反射
元數據(MetaData) 描述數據結構的結構;反射就是得到元數據的行爲。
二、反射引入
- Object obj = new Student();
若程序運行時接收到外部傳入的一個對象,該對象的編譯類型是Object,但程序又需要調用該對象運行類型的方法:
1.若編譯和運行類型都知道,使用 instanceof判斷後,強轉。
2.編譯時根本無法預知該對象屬於什麼類,程序只能依靠運行時信息來發現對象的真實信息,這時就必須使用反射了。
3.要是想得到對象真正的類型,就得使用反射。
三、Class類和Class類實例
- Java程序中的各個Java類屬於同一類事物,描述這類事物的Java類就是Class類。
- 對比提問:衆多的人用一個什麼類表示?衆多的Java類用一個什麼類表示?
人 Person
Java類 Class
- 對比提問: Person類代表人,它的實例對象就是張三,李四這樣一個個具體的人,Class類代表Java類,它的各個實例對象又分別對應什麼呢?
- 對應各個類在內存中的字節碼,例如,Person類的字節碼,ArrayList類的字節碼,等等;
- 一個類被類加載器加載到內存中,佔用一片存儲空間,這個空間裏面的內容就是類的字節碼,不同的類的字節碼是不同的,所以它們在內存中的內容是不同的;
- 一個類在虛擬機中只有一份字節碼;
四、獲得Class對象
- 如何得到各個字節碼對應的實例對象?
- 每個類被加載後,系統會爲該類生成對應的Class對象,通過Class對象可以訪問到JVM中的這個類,3種方式:
- 使用Class類的forName(String className)靜態方法,className表示全限定名;如String的全限定名:java.lang.String;
- 調用某個類的class屬性獲取Class對象,如Date.class會返回Date類對應的Class對象(其實就是得到一個類的一份字節碼文件);
- 調用某個對象的getClass()方法。該方法屬於Object類;
Class<?> clz = new Date().getClass();
獲取對象實例
package reflect;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
enum Gender{
MAN,WOMAN(),NONE{};
}
class User{
}
/**
* 得到Class對象的三種方式:
*
* 1. 通過類的class屬性;
* 類.class;
*、 2. 使用Class.forName(String className);className表示 一個類的全限定名
*
* Class clz = Class.forName("java.util.Date");
* 此時 clz 就在描述 java.util.Date這個類
*
* 3. 通過對象的一個 getClass()方法可以搞定
* Class<?> getClass() 返回此 Object 的運行時類。
*
*/
public class ClassDemo {
String name;
public static void main(String[] args) throws Exception {
//得到Usre的字節碼
Class<User> clz = User.class;
Class<User> clz2 = reflect.User.class;
System.out.println(clz == clz2);
String className = "java.util.Date";
/**
* public static Class<?> forName(String className)
*
*
* Class<?> clz = Class.forName("java.lang.String");
*/
Class<?> clz3 = Class.forName(className);
Class<Date> clzDate = (Class<Date>) clz3;
System.out.println(clzDate);
System.out.println(clz == Class.forName("reflect.User"));//true
List l = new ArrayList();
Class<?> clzList = l.getClass();
//現在獲得l的真實類型
System.out.println(l.getClass());//java.util.ArrayList
//得到對象的真正類型
/**
* enum Gender{
MAN,WOMAN(),NONE{};
}
*/
System.out.println("Gender.MAN= "+Gender.MAN.getClass());//reflect.Gender
System.out.println("Gender.WOMAN= "+Gender.WOMAN.getClass());//reflect.Gender
System.out.println("Gender.NONE= "+Gender.NONE.getClass());//reflect.Gender$1
System.out.println(Map.class);
}
}