java.lang包—类Class应用之Java反射机制是什么,为什么,怎么用。
往往當我們面對一項新的知識時,我們往往需要知道三個方面,它是什么,它能做什么,它比原有知識強在哪里,我們該怎么使用它。當你能夠解決這些問題時,便意味著你已經對這項知識入門了。
一、是什么
Java Reflaction in Action有這么一句話,可以解釋。反射是運行中的程序檢查自己和軟件運行環境的能力,它可以根據它發現的進行改變。通俗的講就是反射可以在運行時根據指定的類名獲得類的信息。
二、為什么
我們為什么要使用反射,它的作用是什么,它在實際的編程中有什么應用。首先我們先明確兩個概念,靜態編譯和動態編譯。
- 靜態編譯:在編譯時確定類型,綁定對象,即通過。?
- 動態編譯:運行時確定類型,綁定對象。動態編譯最大限度發揮了java的靈活性,體現了多????態的應用,有以降低類之間的藕合性。???
我們可以明確的看出動態編譯的好處,而反射就是運用了動態編譯創建對象。那么我們再來看看實際中反射又有什么好處那?往往對比能更加直觀的向我們展示兩者的不同。先從某個代碼案例上來解釋(套用一篇博文的一個例子:http://blog.csdn.net/justdoit_potato/article/details/51011843)若是不用反射,它是這樣的
interface?fruit{??public?abstract?void?eat();?? }??class?Apple?implements?fruit{??public?void?eat(){??System.out.println("Apple");??}?? }??class?Orange?implements?fruit{??public?void?eat(){??System.out.println("Orange");??}?? }??//?構造工廠類?? //?也就是說以后如果我們在添加其他的實例的時候只需要修改工廠類就行了?? class?Factory{??public?static?fruit?getInstance(String?fruitName){??fruit?f=null;??if("Apple".equals(fruitName)){??f=new?Apple();??}??if("Orange".equals(fruitName)){??f=new?Orange();??}??return?f;??}?? }??class?hello{??public?static?void?main(String[]?a){??fruit?f=Factory.getInstance("Orange");??f.eat();??}?? }??可以發現,每當我們要添加一種新的水果的時候,我們將不得不改變Factory中的源碼,而往往改變原有正確代碼是一種十分危險的行為。而且隨著水果種類的增加,你會發現你的factory類會越來越臃腫,不得不說這是一種十分--的做法。(初學者可能會問,我們為什么不直接在main方法中new水果那,我們可能會需要getInstance方法做一些別的事情。。。所以不直接new);而反射無疑是一種聰明的辦法,看代碼。
interface?fruit{??public?abstract?void?eat();?? }??class?Apple?implements?fruit{??public?void?eat(){??System.out.println("Apple");??}?? }??class?Orange?implements?fruit{??public?void?eat(){??System.out.println("Orange");??}?? }??class?Factory{??public?static?fruit?getInstance(String?ClassName){??fruit?f=null;??try{??f=(fruit)Class.forName(ClassName).newInstance();??}catch?(Exception?e)?{??e.printStackTrace();??}??return?f;??}?? }?? class?hello{??public?static?void?main(String[]?a){??fruit?f=Factory.getInstance("Reflect.Apple");??if(f!=null){??f.eat();??}??}?? }??在出現新品種水果的時候,你完全不用去修改原有代碼。從上面的案例中,我們可以清楚的體會到反射的優越性。那么有的人又會問,這個例子能完全明白,但是如果放到實際的編程,應用中,我們又會在什么情況下用到反射那?舉一個看到過的例子,在實際開發中,我們需要把一個包中的class new出來,但是這個包中的類總是需要變動,那么怎么辦,難道總是修改main方法中xxx=new xxx()嗎。這樣無疑是麻煩的。而運用反射。我們可以相應的增加一個配置文件,在里面記錄包中所有的類名,包中類增加時就加一個類名,刪除時就刪除一個類名。讓main方法去讀取這個配置文件中的類名,通過反射獲得實例,完全不用我們去修改main方法中的代碼。反射還有什么用那?他甚至可以修改其他類中的私有屬性。android開發中,我們需要改變一個私有標志位的時候,android源碼并沒有提供set方法,我們又不能改變源碼,怎么辦,反射可以完美解決這個問題。說了這么多,那么我們的開發中,為什么不全部都用反射那?一個原因,開銷,它的開銷是什么昂貴的,隨意盡量在最需要的地方使用反射。
三、怎么用
說完是什么,為什么,我們必然需要掌握如何使用反射,先看反射中涉及了那些方法。
1)獲取類和對象
Class c=Class.forName("className");//注明:className必須為全名,也就是得包含包名,比如,cn.netjava.pojo.UserInfo; Object obj=c.newInstance();//創建對象的實例OK,有了對象就什么都好辦了,想要什么信息就有什么信息了。??
2)獲得構造函數的方法
3)獲得類方法的方法
Method getMethod(String name, Class[] params),根據方法名,參數類型獲得方法 Method[] getMethods()//獲得所有的public方法 Method getDeclaredMethod(String name, Class[] params)//根據方法名和參數類型,獲得public和非public的方法 Method[] getDeclaredMethods()//獲得所以的public和非public方法4)獲得類中屬性的方法
Field getField(String name)//根據變量名得到相應的public變量 Field[] getFields()//獲得類中所以public的方法 Field getDeclaredField(String name)//根據方法名獲得public和非public變量 Field[] getDeclaredFields()//獲得類中所有的public和非public方法看到這些方法,你就可以明白,反射是多么的強大了,當你正確使用這些方法的時候,基本上是掌握了反射的技巧。
參考博文:http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html
總結
以上是生活随笔為你收集整理的java.lang包—类Class应用之Java反射机制是什么,为什么,怎么用。的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java并发编程—ThreadLocal
- 下一篇: 面试题—设计模式篇