1. 程式人生 > >Java內省機制

Java內省機制

pro 編寫 IT java eth type test void clas

內省概述
內省(Introspector)是Java語言對JavaBean類的屬性,事件和方法的默認處理方式
例如: 類User中有屬性name,那麽必定有getName,setName方法,內省就是通過這兩個方法來獲取或者設置name屬性的值。
JavaBean
就是一個滿足了特定格式的Java類

  • 需要提供無參數的構造方法.
  • 屬性私有.
  • 對私有的屬性提供public的get/set方法.

內省類庫

  • java.beans.Introspector:

  • 該類提供了"了解目標JavaBean所支持的屬性,事件和方法"的標準方式。

  • java.beans.BeanInfo:

  • 該接口提供有關獲取JavaBean的顯式信息(公共的屬性,方法,事件等)的方法。

  • java.beans.PropertyDescriptor:

  • 該類描述 JavaBean的屬性信息. 註意,該屬性信息是通過JavaBean的get/set方法推導出的屬性。

示例代碼
? 1.存在類User

public class Student {
    private String name;
    private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }  
}

? 2.通過內省獲取User類的所有屬性:

public class StudentTest {
    public static void main(String[] args) throws IntrospectionException {
        // 通過Introspector.getBeanInfo方法獲取指定JavaBean類的BeanInfo信息
        BeanInfo beanInfo = Introspector.getBeanInfo(Student.class);
        // 通過BeanInfo的getPropertyDescriptors方法獲取被操作的JavaBean類的所有屬性
        // 註意,該屬性是通過get/set方法推斷出來的屬性
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
        // 遍歷所有的屬性
        for (PropertyDescriptor pd : pds) {
            // 獲取屬性的名字
            String propName = pd.getName();
            System.out.println(propName);
            // 獲取屬性的類型
            Class propType = pd.getPropertyType();
            System.out.println(propType);
            // 獲取屬性對應的get方法
            Method getMethod = pd.getWriteMethod();
            System.out.println(getMethod);
            // 獲取屬性對應的set方法
            Method setMethod = pd.getReadMethod();
            System.out.println(setMethod);
        }
    }
}

? 3.創建一個User對象,通過內省,設置該對象的name屬性的值為"張三豐"


// 創建一個沒有任何參數的Student對象s
   Student s = new Student();
   // 通過PropertyDescriptor類的構造方法,直接獲取Student類的name屬性 
   PropertyDescriptor pd = new PropertyDescriptor("name",Student.class);
   // 獲取name屬性對應的set方法
   Method setMethod = pd.getWriteMethod();
   // 調用set方法給上邊創建的s對象的name屬性賦值
   setMethod.invoke(s, "張三豐");
   // 輸出s
   System.out.println(s);

? 4.輸出結果為:
Student [name=張三豐, age=0]
應用場景
在很多JavaWeb框架設計的時候,會使用到內省機制.
如:
? Web開發框架Struts中的FormBean就是通過內省機制來將表單中的數據映射到類的屬性上.
? BeanUtils框架的底層也是通過內省來操作JavaBean對象的.
BeanUtils
BeanUtils是一個由Apache軟件基金組織編寫的,專門用來操作JavaBean對象的一個工具.
主要解決的問題是:可以把對象的屬性數據封裝到對象中。
它的底層,就是通過內省來實現的.

// 向Map集合中封裝數據 -- 模擬在javaWeb中,使用request.getParameterMap() 獲取的參數數據;
Map<String, Object> map = new HashMap<String, Object>() ;
map.put("name", "張三豐") ;
map.put("age", 200) ;
?
// 創建一個Student對象
Student s = new Student();
// 通過BeanUtils的populate方法,可以把Map集合中的數據封裝到Student中
// 該方法的底層就是通過內省來實現的
BeanUtils.populate(s, map);

擴展
內省機制是通過反射來實現的

Java內省機制