反射定義
JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意方法和屬性;這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為java語言的反射機制。
- 理解反射的概念,反射之中包含了一個「反」字,所以了解反射我們先從「正」開始。
1.1)一般情況下,我們使用某個類時必定知道它是什么類,是用來做什么的。于是我們直接對這個類進行實例化,之后使用這個類對象進行操作。
image.png
1.2)反射則是一開始并不知道我要初始化的類對象是什么(或者是第三方的類沒有提供對外的構(gòu)造方法等情況),自然也無法使用 new 關(guān)鍵字來創(chuàng)建對象了。這時候,我們使用 JDK 提供的反射 API 進行反射調(diào)用
image.png
測試類:
ppackage animal;
public class Dog {
private String name;
private int age;
private Dog() {
this.name = "dav";
this.age = 2;
}
public Dog(String name) {
this.name = name;
}
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(String food) {
System.out.println("dog " + name + " eat " + food);
}
private void sleep(int hours) {
System.out.println("dog " + name + " sleep " + hours + " hours");
}
}
反射的相關(guān)操作

反射的基本使用
代理模式定義
給目標對象提供一個代理對象,并由代理對象控制對目標對象的引用。目的:
(1)通過引入代理對象的方式來間接訪問目標對象,防止直接訪問目標對象給系統(tǒng)帶來的不必要復(fù)雜性。
(2)通過代理對象對原有的業(yè)務(wù)增強。

image.png
-
靜態(tài)代理
一個代理對象和真實對象 存在一個確定關(guān)系(一對一 或者 一對多)即是代理對象中的真實對象是確定的。(違反開閉原則,擴展能力差,可維護性差)
公共接口
真實對象
代理對象
訪問者 -
動態(tài)代理:是指在使用時再創(chuàng)建代理類和實例
1)優(yōu)點:只需要1個動態(tài)代理類就可以解決需要創(chuàng)建多個靜態(tài)代理才能處理的問題,避免重復(fù)、多余代碼,更強的靈活性
2)缺點:效率低,相比靜態(tài)代理中 直接調(diào)用目標對象方法,動態(tài)代理則需要先通過Java反射機制,從而間接調(diào)用目標對象方法。
3)應(yīng)用場景局限:因為 Java 的單繼承特性(每個代理類都繼承了 Proxy 類),即只能針對接口 創(chuàng)建 代理類,不能針對類創(chuàng)建代理類。在java的動態(tài)代理機制中,有兩個重要的類或接口,一個是InvocationHandler接口、另一個則是 Proxy類,這個類和接口是實現(xiàn)我們動態(tài)代理所必須用到的。
InvocationHandler接口是給動態(tài)代理類實現(xiàn)的,負責(zé)處理被代理對象的操作的,而Proxy是用來創(chuàng)建動態(tài)代理類實例對象的,因為只有得到了這個對象我們才能調(diào)用那些需要代理的方法。
4)動態(tài)代理實現(xiàn)原理: 通過 Proxy.newProxyInstance()方法動態(tài)生成一個代理類(這個動態(tài)生成的代理類 實現(xiàn)是被代理類 實現(xiàn)的接口),并緩存。用戶獲取到這個代理類后 調(diào)用接口中的方法會走到 invoke 方法中,最后由被代理類的具體實現(xiàn)類來操作方法。(所以動態(tài)代理類中需要實現(xiàn)invocationHandler接口,并完成invoke方法的反射調(diào)用)
5)實現(xiàn)范例

公共接口1

公共接口2

接口2的真實實現(xiàn)

接口1的真實實現(xiàn)

動態(tài)代理類實現(xiàn)

動態(tài)代理的使用





