1. 程式人生 > >java Introspector內省和Reflect反射學習、聯絡和區別

java Introspector內省和Reflect反射學習、聯絡和區別

                        java Introspector內省和Reflect反射學習、聯絡和區別

 

一、反射和內省

1、反射: 將一個類中屬性、方法拆解中一個個集合。 Methods[],Fields[]。 對於任意一個類,可以通過反射獲取所有的屬性和方法;對於任意一個物件可以通過反射呼叫任意一個方法。

2、內省: java提供的一套API,用於操作某個屬性的getter/setter方方法。這些屬性命名必須符合java bean命名規範。 (屬性名的第二個字母是小寫,則轉getter/setter方法時,將第一個字母變成大寫! 待確定!)

3、聯絡: 都是通過反射的原理來操作類的相關屬性和方法。

4、區別: 反射是直接操作類的各種屬性;內省是在反射的基礎上進行了一次封裝。如:使用內省獲取屬性值,肯定會呼叫 getter方法,而反射可以直接獲取到。

 

二、程式碼示例

1、 定義一個普通的java類 User

/**
* description: 定義一個普通的java類,將採用反射reflect 和內省 introspector 進行測試呼叫
* @version v1.0
* @author w
* @date 2018年9月4日下午10:21:20
*/
public class User extends Person {
    private String name;
    private int age;
    // 省略 getter/setter

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }
}

2、使用反射操作類的屬性和方法

@Test
public void reflect() throws Exception{
    // 1.使用反射操作類的屬性和方法
    User user = new User();
    Field nameF = user.getClass().getDeclaredField("name");
    nameF.setAccessible(true);
    nameF.set(user, "小明");

    Field ageF = User.class.getDeclaredField("age");
    ageF.setAccessible(true);
    ageF.set(user, 111);

    System.out.println("姓名:"+nameF.get(user)+" -- 年齡 :"+ageF.getInt(user));
}

 

3、.使用內省操作類的屬性和方法

@Test
public void introspector() throws Exception{

    // 2.使用內省 PropertyDescriptor 操作類的屬性和方法
    User user = new User();
    PropertyDescriptor pd = new PropertyDescriptor("name", User.class);

    // 等價於呼叫 setName() 方法
    Method writeMethod = pd.getWriteMethod();
    writeMethod.invoke(user, "曉紅同學");

    // 等價於呼叫 setAge() 方法
    PropertyDescriptor pd2 = new PropertyDescriptor("age", User.class);
    Method writeMethod2 = pd2.getWriteMethod();
    writeMethod2.invoke(user, 18);

    // 等價於呼叫 getName() 和 getAge() 方法
    Method readMethod = pd.getReadMethod();
    Object name = readMethod.invoke(user);

    Method readMethod2 = pd2.getReadMethod();
    Object age = readMethod2.invoke(user);

    System.out.println("姓名2:"+name+" --- 年齡2:"+age);

    // 3.使用 Introspector 操作所有屬性
    BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
    PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    for (PropertyDescriptor p : propertyDescriptors) {
        // 獲取所有屬性,包含父類屬性
        System.out.println(p);
        // xx do something
    }

    MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
    for (MethodDescriptor m : methodDescriptors) {
        // 獲取所有方法,包含父類方法
        System.out.println(m.getDisplayName());
        // xx do something
    }
}

 

參考資料:https://www.cnblogs.com/winclpt/articles/7405271.html

                   Java內省機制