寫在前面:在面向對象的世界裏(普通數據類型和Java靜態的東西不是面向對象),萬事萬物皆對象,類也是對象,是java.lang.Class對的實例對象,它的實例是每一個對象
反射機制:動態加載類:
====================Class類的使用=================================
Class類的使用:
(1)獲取類類型 Class:
1.類名.class;
2.對象.getClass();
3.Class c = Class.forName("com.reflect.Word");
(2)通過 Word 2 =new Word();對象,是靜態的加載類 ,是在編譯時刻需要加載所有可能會用到的類。
而通過反射Class c = Class.forName("com.reflect.Word");動態加載類,在運行時加載;
Word w = (Word)c.newInstance();通過類類型,創建該類對象。
總結:功能性的類使用動態加載(可以有助於程序的設計)
(3)基本數據類型,void關鍵字都存在類類型
1.Class c1 = int.class//int 的類類型
2.Class c2 = String.class//String 類的類類型
3.Class c3 = double.class;
4.Class c4 = Double.class;
5.Class c5 = void.class;
---------要想動態獲取類的信息,首先獲取該類的類類型-------------
(4)通過反射來獲取到所有類的方法(public)的信息(方法也是對象 Method類,)
Method[] ms = c1.getMethods();//Method對象有其他方法可以獲得方法的返回值類型,參數列表
類型,方法名,等)
(5)通過反射來獲取到所有類的成員變量的信息(成員變量也是對象 Field)
Field[] fs = c1.getDeclaredFields();
(6)獲取構造方法的信息(Constructor)
Class c =obj.getClass();
Constructor[] cs=c.getDeclaredConstructors();//得到自己聲明的構造函數
=============方法的反射=====================================
1)方法的獲取(前面已介紹先獲取類類型)
Method m = c.getMethod(參數名,參數類類型列表數組)
2)方法的反射操作;
m.invoke(該方法所屬類的對象,args)
3)通過反射認識泛型的本質
//反射的操作都是在編譯之後的操作,即運行時的操作
//編譯之後集合的泛型是去泛型化的,Java中集合的泛型,是防止錯誤輸入的,只在編譯階段有效,繞過編譯就無效了
例:
ArrayList list1 = new ArrayList();
ArrayList<String> list2 = new ArrayList<String>();
Class c1= list1.getClass();
Class c2=list2.getClass();
//c1==c2 true;
Method m = c2.getMethod("add",Object.class);
c2.invoke(list2,1);//繞過編譯就繞過了泛型,加入成功