黑馬學習-----------------------內省

很多朋友在深入的接觸 JAVA 語言後就會發現這樣兩個詞:反射 (Reflection) 和內省 (Introspector) ,經常搞不清楚這到底是怎麼回事,在什麼場合下應用以及如何使用?今天把這二者放在一起介紹,因爲它們二者是相輔相成的。

反射

相對而言,反射比內省更容易理解一點。用一句比較白的話來概括,反射就是讓你可以通過名稱來得到對象 ( 類,屬性,方法 ) 的技術。例如我們可以通過類名來生成一個類的實例;知道了方法名,就可以調用這個方法;知道了屬性名就可以訪問這個屬性的值。

還是寫兩個例子讓大家更直觀的瞭解反射的使用方法:

 

// 通過類名來構造一個類的實例
Class cls_str = Class.forName( "java.lang.String" );
// 上面這句很眼熟,因爲使用過 JDBC 訪問數據庫的人都用過 J
Object str = cls_str.newInstance();
// 相當於 String str = new String(); 
 


 

// 通過方法名來調用一個方法
String methodName = "length" ;
Method m = cls_str.getMethod(methodName, null );
System.out.println( "length is " + m.invoke(str, null ));
// 相當於 System.out.println(str.length()); 


 

內省是 Java 語言對 Bean 類屬性、事件的一種缺省處理方法。例如類 A 中有屬性 name, 那我們可以通過 getName,setName 來得到其值或者設置新的值。通過 getName/setName 來訪問 name 屬性,這就是默認的規則。 Java 中提供了一套 API 用來訪問某個屬性的 getter/setter 方法,通過這些 API 可以使你不需要了解這個規則(但你最好還是要搞清楚),這些 API 存放於包 java.beans 中。

一般的做法是通過類 Introspector 來獲取某個對象的 BeanInfo 信息,然後通過 BeanInfo 來獲取屬性的描述器( PropertyDescriptor ),通過這個屬性描述器就可以獲取某個屬性對應的 getter/setter 方法,然後我們就可以通過反射機制來調用這些方法。下面我們來看一個例子,這個例子把某個對象的所有屬性名稱和值都打印出來:

package com.belmeng.test;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

public class TestIntrospector
{
	private String name;

	public static void main(String[] args) throws Exception
	{
		TestIntrospector demo = new TestIntrospector();
		demo.setName("belm");
		BeanInfo info = Introspector.getBeanInfo(demo.getClass(), Object.class);//通過類 Introspector 來獲取某個對象的 BeanInfo信息
		//通過 BeanInfo 來獲取屬性的描述器( PropertyDescriptor ),通過這個屬性描述器就可以獲取某個屬性對應的 getter/setter 方法,然後我們就可以通過反射機制來調用這些方法
		PropertyDescriptor[] p = info.getPropertyDescriptors();
		for (int i = 0; i < p.length; i++)
		{
			System.out.println(p[i].getName() + "="+ p[i].getReadMethod().invoke(demo, null));
			p[i].getWriteMethod().invoke(demo, "hello");//通過反射調用setName方法
			System.out.println(demo.name);
		}
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}
}


 

將 Java 的反射以及內省應用到程序設計中去可以大大的提供程序的智能化和可擴展性。有很多項目都是採取這兩種技術來實現其核心功能,例如我們前面提到的 Struts ,還有用於處理 XML 文件的 Digester 項目,其實應該說幾乎所有的項目都或多或少的採用這兩種技術。在實際應用過程中二者要相互結合方能發揮真正的智能化以及高度可擴展性。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章