1. 程式人生 > >Java反射例項(實戰方能理解jdk的各種方法)

Java反射例項(實戰方能理解jdk的各種方法)

什麼是反射?反射有什麼用處?

1. 什麼是反射?

“反射(Reflection)能夠讓運行於JVM中的程式檢測和修改執行時的行為。”這個概念常常會和內省(Introspection)混淆,以下是這兩個術語在Wikipedia中的解釋:

  1. 內省用於在執行時檢測某個物件的型別和其包含的屬性;
  2. 反射用於在執行時檢測和修改某個物件的結構及其行為。

從它們的定義可以看出,內省是反射的一個子集。有些語言支援內省,但並不支援反射,如C++。

反射和內省

內省示例:instanceof 運算子用於檢測某個物件是否屬於特定的類。

1 2 3 4 if(obj instanceofDog) { Dog d = (Dog) obj; d.bark(); }

反射示例:Class.forName()方法可以通過類或介面的名稱(一個字串或完全限定名)來獲取對應的Class物件。forName方法會觸發類的初始化。

1 2 3 4 5 // 使用反射 Class<?> c = Class.forName("classpath.and.classname"); Object dog = c.newInstance();
Method m = c.getDeclaredMethod("bark",newClass<?>[0]); m.invoke(dog);

在Java中,反射更接近於內省,因為你無法改變一個物件的結構。雖然一些API可以用來修改方法和屬性的可見性,但並不能修改結構。

2. 我們為何需要反射?

反射能夠讓我們:

  • 在執行時檢測物件的型別;
  • 動態構造某個類的物件;
  • 檢測類的屬性和方法;
  • 任意呼叫物件的方法;
  • 修改建構函式、方法、屬性的可見性;
  • 以及其他。

反射是框架中常用的方法。

例如,JUnit通過反射來遍歷包含 @Test

 註解的方法,並在執行單元測試時呼叫它們。(這個連線中包含了一些JUnit的使用案例)

對於Web框架,開發人員在配置檔案中定義他們對各種介面和類的實現。通過反射機制,框架能夠快速地動態初始化所需要的類。

例如,Spring框架使用如下的配置檔案:

1 2 3 <beanid="someID"class="com.programcreek.Foo"> <propertyname="someField"value="someValue"/> </bean>

當Spring容器處理<bean>元素時,會使用Class.forName("com.programcreek.Foo")來初始化這個類,並再次使用反射獲取<property>元素對應的setter方法,為物件的屬性賦值。

Servlet也會使用相同的機制:

1 2 3 4