摘要:四后記理解好對象不僅能讓我們更好的認識一切皆對象這個觀點,對之后學習泛型,類型擦除都是很有幫助的,而對于反射機制我們只需在適當的場合利用它即可。
一 前言
很多書上都說,在java的世界里,一切皆對象。其實從某種意義上說,在java中有兩種對象:實例對象和Class對象。實例對象就是我們平常定義的一個類的實例:
/** * Created by aristark on 3/28/16. */ public class Person { }
然后利用new關鍵字:
public class Person { public static void main(String[] args){ Person p = new Person(); } }
而Class對象是沒辦法用new關鍵字得到的,因為它是jvm生成用來保存對應類的信息的,換句話說,當我們定義好一個類文件并編譯成.class字節碼后,編譯器同時為我們創建了一個Class對象并將它保存.class文件中。我不知道這樣描述是否妥當,因為我也見過某些書上直接把.class文件稱之為Class對象。同時在jvm內部有一個類加載機制,即在需要的時候(懶加載)將.class文件和對應的Class對象加載到內存中。總之要有這樣一個意識,Person.java文件編譯成Person.class的同時也會產生一個對應的Class對象。
二 Class對象的獲得上面說了,Class對象是jvm用來保存對象實例對象的相關信息的,除此之外,我們完全可以把Class對象看成一般的實例對象,事實上所有的Class對象都是類Class的實例。得到一個實例對象對應的Class對象有以下三種方式:
1.通過實例變量的getClass()方法:
Dog dog = new Dog(); Class d = dog.getClass();
2.通過類Class的靜態方法forName():
try { Class dog1 = Class.forName("Dog"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
3.直接給出對象類文件的.class:
Class dog2 = Dog.class;三 Class對象的使用和反射
JAVA反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
簡而言之,我們可以從.class逆向到.java(反編譯),我們可以通過反射機制來訪問一個類java對象的屬性,方法,甚至我們可以輕易改變一個私有成員,看代碼,我們先來定義一個Cat類:
class Cat{ public static int count; public int age; private String name; static { count = 0; } public Cat(){ age = count++; System.out.println("this is class Cat!"); } public void run(){ } private void ruff(){} }
注意到我們的類中包含靜態成員,私有變量,靜態初始化以及私有方法。這里在提一下所謂的懶加載:當Cat.java編譯成Cat.class文件后并不會立即被加載到內存,而是在它的的靜態成員第一次被訪問時才被加載(這么看來,Cat的默認構造方法也是靜態的!)
Class c = Cat.class; Field[] fields = c.getDeclaredFields(); for (Field field : fields){ System.out.println(field); }
結果如下:
public static int Cat.count public int Cat.age private java.lang.String Cat.name
可以看到我們輕而易舉的得到了Cat類的字段信息,再來:
Method[] methods = c.getDeclaredMethods(); for (Method method : methods){ System.out.println(method); }
結果如下 :
public void Cat.run() private void Cat.ruff()
好玩吧,我們竟然可以在運行時得到類的信息。同時我們發現Cat類中的靜態初始化代碼段并沒有執行。接下來我們通過Class對象來獲得對應的實例對象:
try { Cat cat = (Cat) c.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); }
這時候靜態代碼塊執行了:
this is class Cat!
接下來我們做一件神奇的事情:
try { Class catClass = Class.forName("Cat"); Field name = catClass.getDeclaredField("name"); name.setAccessible(true); Cat cat2 = (Cat) catClass.newInstance(); name.set(cat2,"Aristark"); System.out.println(cat2.getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); }
這次我們使用Class.forname()來獲取Class對象,它的作用是讓jvm查找并加載指定的類,也就是說Cat類的靜態代碼塊會被執行。其次值得注意的是,我們通過Class的幾個方法訪問了原本不可以被訪問的name屬性:
this is class Cat! Aristark
從這個意義上來說,反射機制并不符合OOP的思想,所以我們僅在必要的時候使用這個特性就行了。
四 后記理解好Class對象不僅能讓我們更好的認識一切皆對象這個觀點,對之后學習泛型,類型擦除都是很有幫助的,而對于java反射機制我們只需在適當的場合利用它即可。:)關于這兩個知識的深入學習稍后我會貼出一些有借鑒意義的文章,大家要關注哦~
我的微信號是aristark,歡迎交流指正!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65669.html
摘要:反射機制的應用實例在泛型為的中存放一個類型的對象。工廠模式可以參考現在我們利用反射機制實現工廠模式,可以在不修改工廠類的情況下添加任意多個子類。 學習交流群:669823128java 反射 定義 功能 示例概要:Java反射機制詳解| |目錄 1反射機制是什么 2反射機制能做什么 3反射機制的相關API 通過一個對象獲得完整的包名和類名 實例化Class類對象 獲取一個對象的父類與...
近期在維護公司項目的時候遇到一個問題,因為實體類中的 set 方法涉及到了業務邏輯,因此在給對象賦值的過程中不能夠使用 set 方法,為了實現功能,所以采用了反射的機制給對象屬性賦值,借此機會也了解了反射的一些具體用法和使用場景,分以下兩點對反射進行分析: 反射的優勢和劣勢 反射的應用場景 反射的優勢和劣勢 ??個人理解,反射機制實際上就是上帝模式,如果說方法的調用是 Java 正確的打開方式...
摘要:反射機制是什么反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法對于任意一個對象,都能夠調用它的任意一個方法和屬性這種動態獲取的信息以及動態調用對象的方法的功能稱為語言的反射機制反射機制能做什么反射機制主要提供了以下功 反射機制是什么 反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種...
摘要:的動態性反射機制動態編譯動態執行代碼動態字節碼操作動態語言程序運行時可以改變程序得結構或變量類型典型語言等如下代碼不是動態語言但有一定的動態性我們可以利用反射機制字節碼操作獲得類似動態語言的特性的動態性讓編程的時候更加靈活反射機制反射機制指 1.Java的動態性 反射機制 動態編譯 動態執行JavaScript代碼 動態字節碼操作 2.動態語言 程序運行時,可以改變程序得結構或變量...
摘要:一反射機制概念程序運行時,允許改變程序結構或變量類型,這種語言稱為動態語言,如,是動態語言顯然,,不是動態語言,但是有著一個非常突出的動態相關機制。相關的為二獲取源頭重點打開權限所有類的對象其實都是的實例。 一、Java反射機制概念 程序運行時,允許改變程序結構或變量類型,這種語言稱為動態語言,如Python, Ruby是動態語言;顯然C++,Java,C#不是動態語言,但是JAVA有...
閱讀 3528·2021-11-18 10:02
閱讀 3103·2019-08-29 18:34
閱讀 3389·2019-08-29 17:00
閱讀 420·2019-08-29 12:35
閱讀 747·2019-08-28 18:22
閱讀 1910·2019-08-26 13:58
閱讀 1659·2019-08-26 10:39
閱讀 2668·2019-08-26 10:11