java Introspector內省和Reflect反射學習、聯絡和區別
阿新 • • 發佈:2018-11-24
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