3C科技 娛樂遊戲 美食旅遊 時尚美妝 親子育兒 生活休閒 金融理財 健康運動 寰宇綜合

Zi 字媒體

2017-07-25T20:27:27+00:00
加入好友
Java(47)版權聲明:轉載前請留言獲得作者許可,轉載后標明作者 張拭心 與 原文鏈接。大家都是成年人,創作不易,感謝您的支持!什麼是 Reflection 反射,為什麼要用它Java 強類型語言,但是我們在運行時有了解、修改信息的需求,包括類信息、成員信息以及數組信息。Java 中 Reflection 和 Introspection 區別?說起反射,還有一個相似的概念 『Introspection』,字面意思是「自省、內省」,它們之間的區別如下:內省在運行時檢查一個對象的類型或者屬性最常見的例子就是運行時通過 a instanceof A 來判斷 a 對象的類型反射用來在運行時檢查或者修改一個對象信息可以用來實現看似不可能的操作,比如訪問私有方法,動態創建對象可以看到,反射是在內省的基礎上,增加了修改的能力。反射的入口:java.lang.Class日常開發中的對象,分為兩種,基本類型和引用類型:基本類型,(固定的 8 種) 整數:byte, short, int, long小數:float, double字元:char布爾值:boolean引用類型所有的引用類型都繼承自 java.lang.Object類,枚舉,數組,介面都是引用類型java.io.Serializable 介面,基本類型的包裝類(比如 java.lang.Double)也是引用類型對每一種對象,JVM 都會實例化一個 java.lang.Class 的實例,java.lang.Class 為我們提供了在運行時訪問對象的屬性和類型信息的能力。Class 還提供了創建新的類和對象的能力。最重要的是,Class 是調用其他反射 API 的入口,我們必須先獲得一個 Class 實例才可以進行接下來的操作。得到一個 Class 對象除了 java.lang.reflect.ReflectPermission 以外,java.lang.reflect 中的其他類都沒有 public 的構造函數,也就是說要得到這些類,我們必須通過 Class 。下面是幾種得到 Class 對象的不同方法:1.Object.getClass 方法如果我們已經拿到了一個對象,可以很方便地使用它的 getClass 方法獲得一個 Class 對象(當然這僅限於引用類型的對象):Class c = "shixinzhang.top".getClass;返回的對象 c 是 String 類型。enum Sex{ FEMALE, MALE } Class c = FEMALE.getClass;上述例子中 FEMALE 是 枚舉 Sex 的實例,因此 FEMALE.getClass 返回的就是 枚舉類型 Sex 的 Class。byte bytes = newbyte[1024]; Classbyte>c = bytes.getClass;由於數組也是 Object 的一種,因此我們可以調用 getClass 方法獲得 byte 數組類型的 Class。2. .class 語法如果我們當前沒有某個類的對象,無法使用 getClass 方法,那還可以使用另外一種方法獲取 Class:在要獲得的類名后加上 .class ,比如這樣:Integer.class.newInstance; int.class.newInstance可以看到,這種方式不僅能用於引用類型,基本類型也可以。當然數組也可以嘍:Class b = int.class;3.Class.forName如果我們有一個類的完整路徑,就可以使用 Class.forName(「類完整的路徑」) 來得到相應的 Class,這個方法只能用於引用類型,比如:Class c = Class.forName("java.lang.String"); Class aClass = Class.forName("top.shixinzhang.androiddemo2.beans.BookBean");4.靜態屬性 TYPE 上面介紹,使用 .class 後綴可以很方便地獲得基本類型的 Class。對於基本類型和 void 的包裝類,還有另外一種方式獲得 Class,那就是靜態屬性 TYPE 。每個包裝類都有 TYPE 屬性,以 Double 為例:TYPE = (Class) double.class.getComponentType;可以看到這個屬性就是使用 .class 的方式獲得 Class 並保存。因此我們可以直接調用包裝類的 TYPE:ClassintegerWrapper = Integer.TYPE; ClassdoubleWrapper = Double.TYPE; ClassvoidWrapper = Void.TYPE;5.返回 Class 的方法如果我們已經有了一個 Class,可以使用下面的一些方法來獲得它相關的類:Class.getSuperclass 返回調用類的父類Class.getClasses 返回調用類的所有公共類、介面、枚舉組成的 Class 數組,包括繼承的Class.getDeclaredClasses 返回調用類顯式聲明的所有類、介面、枚舉組成的 Class 數組Class.getDeclaringClassjava.lang.reflect.Field.getDeclaringClassjava.lang.reflect.Method.getDeclaringClassjava.lang.reflect.Constructor.getDeclaringClass 返回類/屬性/方法/構造器所在的類Class 的修飾符:Modifier一個 Class 可以被以下修飾符的一種或者多種修飾:訪問許可權控制符:public, protected, private抽象的、需要實現的:abstract限制只能有一個實例的:static不允許修改的:final線程同步鎖:synchronized原生函數:native採用嚴格的浮點精度:strictfp介面註解當然上面的修飾符不是所有 Class 都可以修飾,比如:Interface 不能是 final 的enum 不能是 abstract 的java.lang.reflect.Modifier提供了對 Class 修飾符的解碼,我們可以使用Class.getModifiers獲得調用類的修飾符的二進位值,然後使用Modifier.toString(int modifiers)將二進位值轉換為字元串,Modifier.toString方法實現如下:publicstatic java.lang.String toString(int modifiers) { StringBuilder buf = new StringBuilder; if (isPublic(modifiers)) { buf.append("public "); } if (isProtected(modifiers)) { buf.append("protected "); } if (isPrivate(modifiers)) { buf.append("private "); } if (isAbstract(modifiers)) { buf.append("abstract "); } if (isStatic(modifiers)) { buf.append("static "); } if (isFinal(modifiers)) { buf.append("final "); } if (isTransient(modifiers)) { buf.append("transient "); } if (isVolatile(modifiers)) { buf.append("volatile "); } if (isSynchronized(modifiers)) { buf.append("synchronized "); } if (isNative(modifiers)) { buf.append("native "); } if (isStrict(modifiers)) { buf.append("strictfp "); } if (isInterface(modifiers)) { buf.append("interface "); } if (buf.length == 0) { return""; } buf.setLength(buf.length - 1); return buf.toString; }注意:Interface 默認是 abstract 的,雖然我們沒有添加,編譯器會在編譯器為每個 Interface 添加這個修飾符。只有被 @Retention(RetentionPolicy.RUNTIME) 修飾的註解才可以在運行時被發射獲取Java 中預定義的註解 @Deprecated@Override, 和 @SuppressWarnings 中只有 @Deprecated 可以在運行時被訪問到java.lang.reflect.Member是一個介面,代表 Class 的成員,每個成員都有類型,分為是否從父類繼承,還有是否可以直接訪問。Member 有三個實現類:java.lang.reflect.Constructor:表示該 Class 的構造函數java.lang.reflect.Field:表示該 Class 的成員變數java.lang.reflect.Method:表示該 Class 的成員方法獲取構造函數java.lang.Class提供了以下方法用於獲取該類的構造函數:注意:構造函數無法從父類繼承java.lang.Class提供了以下方法用於獲取該類的成員變數:獲取成員方法提供了以下方法用於獲取該類的成員方法:

本文由yidianzixun提供 原文連結

寫了 5860316篇文章,獲得 23313次喜歡
精彩推薦