<b>閱讀目錄</b>
<a href="http://www.cnblogs.com/kaituorensheng/p/7398069.html#_label0">1. 介紹</a>
<a href="http://www.cnblogs.com/kaituorensheng/p/7398069.html#_label1">2. Java反射相關操作</a>
<a href="http://www.cnblogs.com/kaituorensheng/p/7398069.html#_label2">3. 分析</a>
反射是一種能夠在程式運作時動态通路、修改某個類中任意屬性和方法的機制。
具體:
對于任意一個類,都能夠知道這個類的所有屬性和方法
對于任意一個對象,都能夠調用它的任意一個方法和屬性
在運作時,當加載完類之後,JVM在堆記憶體中會自動産生一個Class類型的對象,這個對象包含了完整的類的結構資訊
這個Class對象就像一面鏡子,透過這個鏡子看到類的結構

那麼,如何得到這個Class對象呢?以下可否
答案是不行的,因為Class的構造函數定義為私有的,隻有JVM可以通路
Class對象擷取的三種方式
舉例
<a></a>
輸出
本文以Student類為例:
接口
類
以下具體介紹下具體的用法
2.1 類名稱、包名
1
2
3
<code>getSimpleName:Student</code>
<code>getName:com.example.refs.Student</code>
<code>getPackage:package: com.example.refs</code>
2.2 方法
結果
4
5
6
7
8
9
10
11
12
13
14
15
<code>getMethods: </code><code>public</code> <code>void</code> <code>com.example.refs.Student.read()</code>
<code>getMethods: </code><code>public</code> <code>void</code> <code>com.example.refs.Student.setId(</code><code>int</code><code>)</code>
<code>getMethods: </code><code>public</code> <code>final </code><code>void</code> <code>java.lang.Object.wait() throws java.lang.InterruptedException</code>
<code>getMethods: </code><code>public</code> <code>final </code><code>void</code> <code>java.lang.Object.wait(</code><code>long</code><code>,</code><code>int</code><code>) throws java.lang.InterruptedException</code>
<code>getMethods: </code><code>public</code> <code>final native </code><code>void</code> <code>java.lang.Object.wait(</code><code>long</code><code>) throws java.lang.InterruptedException</code>
<code>getMethods: </code><code>public</code> <code>boolean java.lang.Object.</code><code>equals</code><code>(java.lang.Object)</code>
<code>getMethods: </code><code>public</code> <code>java.lang.String java.lang.Object.toString()</code>
<code>getMethods: </code><code>public</code> <code>native </code><code>int</code> <code>java.lang.Object.hashCode()</code>
<code>getMethods: </code><code>public</code> <code>final native java.lang.Class java.lang.Object.getClass()</code>
<code>getMethods: </code><code>public</code> <code>final native </code><code>void</code> <code>java.lang.Object.notify()</code>
<code>getMethods: </code><code>public</code> <code>final native </code><code>void</code> <code>java.lang.Object.notifyAll()</code>
<code>getDeclaredMethods: </code><code>public</code> <code>void</code> <code>com.example.refs.Student.read()</code>
<code>getDeclaredMethods: </code><code>private</code> <code>int</code> <code>com.example.refs.Student.getId()</code>
<code>getDeclaredMethods: </code><code>public</code> <code>void</code> <code>com.example.refs.Student.setId(</code><code>int</code><code>) </code>
指定方法
異常
原因:setId為私有方法,利用反射時會進行安全檢查,用setAccessible(true)不進行安全檢查,可以直接對調用私有方法、修改私有變量
2.3 構造函數
2.4 成員變量
getDeclaredFields()獲得某個類的所有申明的字段,即包括public、private和proteced,但是不包括父類的申明字段。
getFields()獲得某個類的所有的公共(public)的字段,包括父類。
2.5 修飾符
2.6 父類
2.7 接口
2.8 建立對象執行個體
舉例用2種方法建立
<code>com.example.refs.Student@72ea2f77</code>
<code>com.example.refs.Student@33c7353a</code>
<code>com.example.refs.Student@681a9515</code>
2.9 注解
自定義一個注解
注:RetentionPolicy.RUNTIME 這個表示運作期注解,這樣在反射的時候才能取到
2.10 泛型
參數類型、傳回值類型舉例
<code>#:java.util.Map<java.lang.String, com.example.refs.Student></code>
<code>泛型類型:class java.lang.String</code>
<code>泛型類型:class com.example.refs.Student</code>
<code>#:java.util.List<com.example.refs.Student></code>
<code>Returntypejava.util.Map<java.lang.Integer, com.example.refs.Student></code>
<code>傳回值,泛型類型:class java.lang.Integer</code>
<code>傳回值,泛型類型:class com.example.refs.Student</code>
2.11 數組
<code>array[0]:123</code>
<code>array[1]:124</code>
<code>array[2]:125</code>
<code>intArray是否是數組類型:</code><code>true</code>
<code>intArray成員類型:int </code>
3.1 使用場景
操作因通路權限限制的屬性和方法
實作自定義注解
動态加載第三方jar包
按需加載類,節省編譯和初始化APK的時間
3.2 優缺點
優點:靈活、自由度高:不受類的通路權限限制
缺點
性能問題:通過反射通路、修改類的屬性和方法時會遠慢于直接操作,但性能問題的嚴重程度取決于在程式中是如何使用反射的。如果使用得很少,不是很頻繁,性能将不是問題
安全性問題:反射可以随意通路和修改類的所有狀态和行為,破壞了類的封裝性,如果不熟悉被反射類的實作原理,随意修改可能導緻潛在的邏輯問題
相容性問題:因為反射會涉及到直接通路類的方法名和執行個體名,不同版本的API如果有變動,反射時找不到對應的屬性和方法時會報異常
3.3 說明
通過反射通路方法比執行個體慢很多
有用到反射的類不能被混淆
反射存在性能問題,但使用不頻繁、按需使用時,對程式性能影響并不大
反射存在安全性問題,因為可以随意修改類的所有狀态和行為(包括private方法和執行個體)
使用反射通路Android的API時需要注意因為不同API版本導緻的相容性問題
3.4 性能對比
不使用反射、啟用安全檢查、啟用安全檢查進行對比
結果對比
差異
耗時(ms)
沒用反射
952
取消安全檢查
4283
啟用安全檢查
14892
本文轉自jihite部落格園部落格,原文連結:http://www.cnblogs.com/kaituorensheng/p/7398069.html,如需轉載請自行聯系原作者