反射——Java高級(jí)開(kāi)發(fā)必須懂的
1 類實(shí)際上都是java.lang.class的實(shí)例對(duì)象。
Class類實(shí)例的表示:
?? eg:class FOO{...} 其本身就是Class類的實(shí)例
可以通過(guò)三種方式創(chuàng)建
<ol>
<li>
Class c1=Foo.class;(任何一個(gè)類都有這個(gè)隱含的靜態(tài)變量)
</li>
<li>
Class c2=foo1.getClass();(foo1是FOO的對(duì)象,創(chuàng)建過(guò)程省略)
</li>
<li>
Class c3=Class.forName("com.imooc.reflect.Foo");(""中為包名類名)
</li>
<u>得到的c1,c2,c3都是相等的,因?yàn)樗鼈兌际潜硎綟oo類的類類型</u>
即<b>Foo類是Class類的對(duì)象,foo1是FOO類的對(duì)象</b>
<p >可以通過(guò)類的類類型來(lái)創(chuàng)建該類的對(duì)象</p>
FOO foo2=c1.newInstance();
2 動(dòng)態(tài)加載和靜態(tài)加載
編譯時(shí)加載類是靜態(tài)加載類
運(yùn)行時(shí)加載類是動(dòng)態(tài)加載類
new創(chuàng)建的對(duì)象是靜態(tài)加載類,在編譯時(shí)就需要加載所有可能用到的類。
但有時(shí)胡應(yīng)用場(chǎng)景是有一個(gè)類能夠用到我就想用,而不管其他類是否可用。
此時(shí)就需要用到動(dòng)態(tài)加載類了。
Class c=Class.forName(arg[0]);
OfficeAble a=c.newInstance();
...
則我們只需要讓W(xué)ord類和Excel類實(shí)現(xiàn)OfficeAble接口,運(yùn)行時(shí)傳入Word類或者Excel類的包名類名就可以了
3 基本類型以及其封裝類 等都是有類類型的。
Class c1=int.class;
Class c2=String.class;
<b>注意 兩者不同</b>
{
Class c3=double.class;
Class c4=Double.class;
}
<b>Class c5=Void.class;</b>
PS:
Class c=obj.getClass();以子類為準(zhǔn),具體傳遞的是哪個(gè)子類的對(duì)象,這個(gè)c就是該子類的類類型。
方法:
getName/getSimpleName
Method 類---一個(gè)成員方法即一個(gè)Method類對(duì)象
getMethods()----獲取所有public的方法,包括繼承而來(lái)的。
getDeclaredMethods()----獲取所有自己聲明的方法,不問(wèn)訪問(wèn)權(quán)限。
Field類---成員變量的操作
getFields----獲取所有public的成員
getDeclaredFields----獲取自己聲明的所有的成員變量
Constructor---構(gòu)造函數(shù)信息(構(gòu)造函數(shù)一定都是自己聲明的)
方法的名稱和參數(shù)列表唯一決定一個(gè)方法
Method m=c.getMethods("Print",new Class);
得到方法對(duì)象之后通過(guò)其實(shí)現(xiàn)方法調(diào)用
m.invoke(a1,new object);
(其實(shí)就是一種反向操作)
PS : ...表示是可變參數(shù)
4 *
反射的操作都是編譯之后的操作,編譯之后,集合的泛型是去泛型化的。---集合泛型是為了防止錯(cuò)誤輸入,所以只在編譯時(shí)有效,繞過(guò)編譯自然就無(wú)效了。
5 應(yīng)用場(chǎng)景
(1)JDBC連接數(shù)據(jù)庫(kù)
(2)代碼生成工具的實(shí)現(xiàn)
(3)各種IDE
(4)接口通過(guò)反射獲取
(5)主流框架的實(shí)現(xiàn)