Java反射機制(一)
結合Oracle官方通過JDK8編寫的反射教程,複習一下反射的知識。結尾篇補一個小例子。
主要內容
這次部落格的主要內容就是簡單介紹反射的概念以及相關獲取類資訊的反射API。
反射的概念
反射是一種在執行時獲取以及修改應用行為的一種工具。我個人的理解就是,new是一種正向的操作,知道現有系統中會出現什麼。反射就是反著來,不知道系統中可能會需要什麼樣的類,通過全限定類名的方式,在需要的時候將它反射出來,同時可以通過反射獲取類的內部資訊。在Java框架的開發中,反射技術運用比較常見。
反射的優缺點
優點
- 強大的擴充套件性,使用者可以通過全限定類名的方式去使用外部定義的類。
- 幫助IDE開發工具獲取使用者正在開發的code的資訊,提示寫出更正確的程式碼。
- 利於除錯工具獲取執行時資訊以及測試類框架的使用比如Junit。
缺點
- 影響效能。 因為反射需要動態的解析類的資訊,相比於非反射使用的方式要慢。
- 對安全環境有要求。 反射需要獲取一定的執行時許可權,在特定的安全環境下不一定存在。
- 暴露了內部的封裝,可能會引起一些負面效果。比如不該被外部呼叫的私有方法,通過反射被呼叫了。
通過反射獲取類資訊
Java中除了基本型別就是引用型別。
boolean,int,long,float等就是基本型別
java.lang.String,Java.io.Serializable就是引用型別
獲取java.lang.Class
對於每一種型別,Java提供了java.lang.Class這個類用於獲取執行時類的屬性和方法資訊。同時java.lang.Class也可以用於建立類和物件。
如果是物件型別的話,可以通過其最上層父類Object提供的getClass()方法獲取Class類。
"apple".getClass();
複製程式碼
如果是基本型別或者對於一個普通的類來說,可以使用.class的方式來獲取Class類,如下。
int.class;
java.io.PrintStream.class;
複製程式碼
當獲取到類的全限定類名後,可以通過Class.forName建立一個類,如下。
Class c = Class.forName("com.coderising.kailuncen.Main");
複製程式碼
獲取類的相關類資訊
以下Api可以用於獲取類的相關類資訊。
獲取類的父類資訊:
Class.getSuperclass()
複製程式碼
獲取類的成員類資訊,不包括私有的:
Class.getClasses()
複製程式碼
獲取類的所有成員類資訊,包括私有的:
Class.getDeclaredClasses()
複製程式碼
以下API可以返回宣告瞭這些成員變數的類的Class資訊。
Class.getDeclaringClass()
java.lang.reflect.Field.getDeclaringClass()
java.lang.reflect.Method.getDeclaringClass()
java.lang.reflect.Constructor.getDeclaringClass()
複製程式碼
如果這個類是匿名類的話,可以通過如下API獲取包含它的類的類資訊。
Class.getEnclosingClass()
複製程式碼
獲取類的修飾符
類在執行期間可以被多種修飾符修飾,如下所示
訪問限定符: public, protected, and private。
需要override的修飾符:abstract。
然後static,final,Annotations等。
反射API可以使用如下方法去訪問他們。
Class.getModifiers()
Class.getAnnotations();
複製程式碼
獲取類的成員資訊
在oracle的教程中,整理了三個表格,介紹瞭如何獲取類的成員資訊。