Java內省機制小總結
Java中的反射機制是通過名稱得到類的方法和對象的成份,對於一切Java類都是適用的,但是有時候使用起來比較麻煩。而JavaBean是一種特殊的Java類,遵守JavaBean的規範,即所有的成員都是私人成員,且每個成員都有公開的讀取和設定的方法(getter和setter),且這些方法都遵守命名的規範。就是因為JavaBean有這些的特性,sun推出了一種專門對JavaBean成員進行訪問的技術,方便對其的訪問,就是內省技術。
首先,內省使用的幾個類(介面)為java.beans.PropertyDescriptor,java.beans.Introspector和java.beans.beanInfo。其中的PropertyDescriptor是對一個Bean屬性的描述,它提供了一系列對Bean屬性進行操作的方法,Introspector是一個工具類,提供了一系列取得Bean資訊的方法,beanInfo是對一個Bean的描述,可以通過它取得Bean內部的資訊。
下面有幾個小的DEMO
首先是定義一個Bean,見下面代碼:
package com.heima.domain;public class Student {private String name;private int age;private Address address;@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + ", address="+ address + "]";}public Student() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}public Student(String name, int age, Address address) {this.name = name;this.age = age;this.address = address;}}
下面對Bean的一個屬性進行賦值:
private void setValue() throws Exception {Student student = new Student();//得到對屬性的描述PropertyDescriptor descriptor = new PropertyDescriptor("name", Student.class);//得到寫方法Method method = descriptor.getWriteMethod();//使用反射調用方法,進行賦值method.invoke(student, "狗蛋兒");System.out.println(student);}
再來一個對Bean所有屬性進行賦值的例子:
private void copyProperties2(HttpServletRequest request) throws Exception {Map<String, String[]> map = request.getParameterMap();Student student = new Student();//得到參數Mapfor (Map.Entry<String, String[]> me : map.entrySet()) {String name = me.getKey();String[] values = me.getValue();//分別得到每個每個屬性的描述對象PropertyDescriptor descriptor = new PropertyDescriptor(name, Student.class);Method method = descriptor.getWriteMethod();//這裡因為Values可能是一個數組,不強轉為一個對對象會出現異常if (values.length > 1) {method.invoke(student, (Object)values);} else {method.invoke(student, values);}}}
我們可以看到使用內省機制對Bean屬性進行操作還是很複雜的,那肯定有人來做工具協助完成這一系列的操作,最後再來一個使用Map對Bean中的屬性進行賦值的例子
private void copyProperties(HttpServletRequest request) {Student student = new Student();try {BeanUtils.populate(student, request.getParameterMap());//使用BeanUtils的populate方法,將Map中的索引值對賦值到Bean中} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}
其中使用了BeanUtils的一些方法,BeanUtils帶包名是org.apache.commons.beanutils.BeanUtils;是apache給出的,用來解決使用內省機制繁瑣的問題。使用時要匯入兩個包:commons-beanutils-1.9.2.jar和commons-logging-1.1.1.jar。
使用內省機制要比反射簡單一點,使用工具後這種差異更明顯了,在Web的工作中可以多少使用,或者自己再封裝一下,用著更順手^^.