反射

1.Class類:

有了元對象,Reflection也成了一件順其自然的事情。有了Reflection,Java也就擁有了動態擴展的能力,這樣就可以極大的提高程序的靈活性。

 1.1 new和newInstance:
    new關鍵字是強類型的,效率相對較高。
    newInstance()是弱類型的,效率相對較低。

newInstance是通過反射創建對象的,在創建一個類的對象的時候,你可以對該類一無所知,一些開源框架比如Spring內部大都是通過反射來創建實例的,當然這種方法創建對象的時候必須擁有該類的句柄,甚至必要的時候還要有相關的權限設置(比如無參構造函數是私有的),
而句柄是可以動態載入的,實際上JVM內部也是這樣加載類的。該方法創建對象的時候,只會調用該類的無參數構造函數,不會調用其他的有參構造函數。
new 後面接類名參數,是最常見的創建實例的方式。這是必須要知道一個明確的類才能使用
    既然使用newInstance()構造對象的地方通過new關鍵字也可以創建對象,爲什麼又會使用newInstance()來創建對象呢?
    假設定義了一個接口Door,開始的時候是用木門的,定義爲一個類WoodenDoor,在程序裏就要這樣寫 Door door = new WoodenDoor() 。假設後來生活條件提高,換爲自動門了,定義一個類AutoDoor,這時程序就要改寫爲 Door door = new AutoDoor() 。雖然只是改個標識符,如果這樣的語句特別多,改動還是挺大的。於是出現了工廠模式,所有Door的實例都由DoorFactory提供,這時換一種門的時候,只需要把工廠的生產模式改一下,還是要改一點代碼。
    而如果使用newInstance(),則可以在不改變代碼的情況下,換爲另外一種Door。具體方法是把Door的具體實現類的類名放到配置文件中,通過newInstance()生成實例。這樣,改變另外一種Door的時候,只改配置文件就可以了。示例代碼如下:
String className = 從配置文件讀取Door的具體實現類的類名; 
Door door = (Door) Class.forName(className).newInstance();
    再配合依賴注入的方法,就提高了軟件的可伸縮性、可擴展性。

Class.forName(String className)這個方法傳入一個類型的全路徑的名字(也就是帶包的完整名字),會返回一個字節碼類型(也就是Class類型)的實例

如:Class clazz = Class.forName("com.dean.Person");

然後再用這個字節碼類型的實例clazz調用newInstance()方法會返回一個Object類型的對象

如下:Object object = clazz.newInstance();

這個object當然不能直接調用Perosn類的方法了,因爲他是Object類型

這個時候就需要強制類型轉換了

Person person = (Perosn)clazz.newInstance();

 

1.2:Field??

關於獲取類的字段有兩種方式:getFields()和getDeclaredFields()。我們先來看看這兩者的區別吧:

getFields():獲得某個類的所有的公共(public)的字段,包括父類中的字段。 
getDeclaredFields():獲得某個類的所有聲明的字段,即包括public、private和proteced,但是不包括父類的申明字段。

優秀文件鏈接:http://blog.csdn.net/disiwei1012/article/details/53022321

在Java的反射機制中,

通過 數組的 class 對象的getComponentType()方法可以取得一個數組的Class對象, 通過Array.newInstance()可以反射生成數組對象,看示例代碼:



 




  優秀連接文章:1:http://blog.csdn.net/gudu1289/article/details/46638495。2:http://blog.csdn.net/dean_deng/article/details/44726083 3:http://www.cnblogs.com/yrstudy/p/6500982.html; 4:http://blog.csdn.net/claram/article/details/53412256

 

發佈了25 篇原創文章 · 獲贊 0 · 訪問量 4750
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章