Java基礎之內省機制

內省機制


Java中提供了一套API用來訪問某個屬性的getter/setter方法,這些API存放與包java.beans中,一般的做法是通過類Introspector的getBeanInfo方法來獲取摸個對象的BeanInfo信息,然後通過BeanInfo來獲取屬性的描述器(PropertyDescriptor),通過這個屬性描述器就可以獲取某個屬性對應的getter/setter方法,然後我們就可以通過反射機制來調用這些方法。

內省機制用於查看和操作JavaBean中的屬性:
1)獲取JavaBean中的每一個屬性名、屬性類型
2)通過getter方法獲取屬性值,通過setter方法給屬性設置值

Introspector相關API


Introspector類
Introspector類提供了一種標準的方式作爲工具獲取類的屬性、事件、方法。
static BeanInfo getBeanInfo(Class<?> beanClass)在Java Bean上進行內省,瞭解其所有屬性、公開的方法和事件。

BeanInfo類
該類爲Java Bean提供有關其Bean的方法、屬性、事件等顯示信息
MethodDescription[] getMethodDescriptors() 獲得方法相關的描述器
EventSetDescriptors[] getEventSetDescriptors() 獲得事件相關的描述去
PropertyDescriptor[] getpropertyDescriptors() 獲得屬性相關的描述器

PropertyDescriptor類
Method getReadMethod() 獲取用於讀取屬性值的方法
Method getWriteMethod()獲取用於寫入屬性值的方法

MethodDescriptor類
Method getMethod() 獲得此MethodDescriptor封裝的方法

使用內省機制


創建一個User類,我們爲name屬性添加setter方法,爲age屬性添加getter方法。

public class User {
	private String name;
	private int age;
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
 }

我們使用上面的User類進行測試

//獲取JavaBean的描述對象
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
//獲取JavaBean中屬性的描述器
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
	System.out.println(pd.getName());
	System.out.println(pd.getReadMethod());
	System.out.println(pd.getWriteMethod());
	System.out.println("====================");			
}

程序的執行結果如下

age
introspector.User.getAge()
null
====================
class
public final native java.lang.Class java.lang.Object.getClass()
null
====================
name
null
introspector.User.setName(java.lang.String)
====================

我們可以看到,我們並沒有class屬性,可是它是哪來的?
我們知道,其父類Object含有getClass方法,這個class屬性就是來自其父類。
如果我們不需要這個class屬性,我們可以使用Introspector提供的getBeanInfo的重載方法將Object排除,從而獲取User及User父類的屬性,但是不包括Object類中的屬性

getBeanInfo(Class<?> cls, Class<?> stopClass)

使用內省機制實現BeanUtils


//Bean -> Map
public static Map<String, Object> bean2Map(Object object) throws Exception {
	Map<String, Object> map = new HashMap<String, Object>();
	BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass(),Object.class);
	PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
	for (PropertyDescriptor pd : pds) {
		String key = pd.getName();
		Object value = pd.getReadMethod().invoke(object);
		map.put(key, value);
	}
	return map;
}
//Map -> Bean
public static <T> T map2Bean(Map<String, Object> map, Class<T> beanType) throws Exception {
	Object object = beanType.newInstance();
	BeanInfo beanInfo = Introspector.getBeanInfo(beanType,Object.class);
	PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
	for (PropertyDescriptor pd : pds) {
		Object value = map.get(pd.getName());
		pd.getWriteMethod().invoke(object, value);
	}
	return (T) object;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章