由淺入深玩反射

說到反射,相信做過java開發的人肯定都或多或少都聽說過,但是在項目中用到反射的就很少很少,為什麼今天要和大家聊反射呢,因為最近我準備給大家講講spring的AOP的,AOP的底層就用到了動態代理,而動態代理裡面用到了反射,所以就想先和大家先聊聊反射,再一層層的去扒spring的AOP的外衣;

先來一波反射的定義:java反射是在運行狀態中,對於任意一個類,都能夠知道這個類的屬性和方法;對於任意一個對象都可以調用它的任意方法和屬性,這種動態獲取信息以及動態調用對象的方法的功能反射;

其實上面這段話有個重點就是在運行狀態中,而非編譯狀態中,我先帶大家了解兩個概念,然後寫個小例子,你大概就知道,反射到底有什麼好處了,現在我給大家說一下靜態編譯和動態編譯的概念:

Advertisements

靜態編譯:在編譯時確定類型,綁定對象,即通過;

動態編譯:運行時確定類型,綁定對象,動態編譯發揮了java的靈活性,體現了java的多態性,以及降低了類之間的耦合性;

先給大家介紹一下反射的基本操作,然後來一個例子來說明反射的作用;

1:獲取CLass(獲取Class有三種方法)

1.1:通過Class.forName(全限定名);

1.2:通過類的實例來獲取(實例.getClass());

1.3:通過類名來獲取(類名.class);

如下圖1.1:

1.1

2:實例化對象

2.1:如果只有無參的構造器可以直接通過Class.newInstance()來實例化對象;

2.2:如果類中有既有無參構造器也有無參構造器,如果想實例化有參構造函數則需要先得到Constructor再調用newInstance(),如下圖2.2:

Advertisements

2.2

3:方法的調用:

3.1:先通過getMethod()得到method,然後再調用invoke()方法,如下圖3.1

3.1

小操作完,現在來一波例子,例子直接截圖了:

定義了一個friut介面

介面實現類

介面實現類

實現了一個工廠類和一個測試方法

通過上面的代碼我們可以發現,當我們有一個新的水果加入時,我們就得改變我們得工廠,當水果越來越多時,工廠裡面的代碼會越來越多,但是如果我們利用反射就會避免這個問題,部門代碼改變如下:

通過上面的代碼我們看到反射的優越性,就算再增加水果我們也不需要改變原來工廠的代碼了。其實通過反射還可以驗證java泛型的一個特性就是泛型的擦除性,在運行期間其實泛型是被擦除的,這裡我就不寫這個代碼了,如果比較感興趣的童鞋可以加我微信,到這裡反射就說完了,可能上面還有很多寫的不足的地方希望大家能夠指正並提出您的寶貴意見,下一節我跟大家聊一聊動態代理;

Advertisements

你可能會喜歡