反射(一)
一 引出反射和什麼是反射
問題1:
1.物件有編譯型別和執行型別
Object obj = new java.util.Date();
編譯型別: Object
執行型別: java.util.Date
需求:通過obj物件,呼叫java.util.Date類中的toLocaleString方法.
obj.toLocaleString(); 此時編譯報錯, 編譯時,會檢查該編譯型別中是否存在toLocaleString方法.
如果存在,編譯成功,否則編譯失敗.
解決方案,因為obj的真實型別是java.util.Date類,所以我們可以把obj物件強制轉換為java.util.Date型別. java.util.Date d = (java.util.Date
d.toLocaleString();//呼叫成功
如果不知道obj的真實型別,就不能強轉.(底層有一個方法,返回一個Object型別的java.util.Date物件).
底層程式碼: ------public static Object getObject(){ return new java.util.Date(); }
此時問題如何解決?
問題2:
我在面向物件中提及到,一切事物都可以看成是物件,那麼問題來了,類這種事物是啥物件呢?
又使用什麼類來表示類這種物件呢?
二 Class類和Class例項
Class類:用來描述類或者介面的型別,描述類的類
Class例項:在JVM中的一份份位元組碼,Class例項表示在JVM中的類或者介面,
列舉是一種特殊的類,註解是一種特殊的介面
如何建立Class物件,如何表示一個位元組碼物件
方式1,通過屬性class
方式2 通過物件的getClass方法
方式3 通過Class類中的靜態方法forName(String className)
注意:同一個類在JVM中只存在一份位元組碼物件,也就是說clazz1==clazz2==clazz3
三 九大內建Class例項和陣列的Class例項
問題:在上述講了三種獲取Class物件的方式,基本資料型別不能表示為物件,也就不能使用getClass的方式,基本型別沒有類名的概念,也不能使用Class.forName的方式,
如何表示基本型別的位元組碼物件呢?
所有的資料型別都有class屬性.
Class clz = 資料型別.class;
九大內建Class例項: JVM中預先提供好的Class例項,分別:byte,short,int,long,float,double,boolea,char,void. 表示:byte.class,short.class,int.class,....void.class.
在8大基本資料型別的包裝類中,都有一個常量:TYPE,用於返回該包裝類對應基本類的位元組碼物件. System.out.println(Integer.TYPE == int.class);//true 注意:Integer和int是不同的資料型別 System.out.println(Integer.class == int.class);//false
陣列的Class例項:
陣列是引用資料型別,陣列其實是物件. 如何來表示陣列的Class例項.
方式1: 陣列型別.class;
方式2: 陣列物件.getClass();
注意:所有的具有相同的維數和相同元素型別的陣列共享同一份位元組碼物件,
和元素沒有關係.
Class: 描述所有的型別,所以Class類中應該具有所有型別的相同的方法.
Object: 描述所有的物件,所以在Object類中應該具有所有物件的共同的方法.