内省
Wiki 定义
在计算机科学中,内省是指计算机程序在运行时,检查对象类型的一种能力,通常也可以称作运行时类型检查
java定义
从
java Bean
的角度来看,这里的对象就是bean
对象,主要关注点是属性、方法和事件,也就是运行时可以获取到相应的信息今夕一些处理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EXfeSdlZ-1647321008695)(/Users/bingye/Library/Application Support/typora-user-images/image-20220315123111870.png)]
操作的范围包括但是不局限与java Beans
的属性,事件和方法
Demo
// 定义一个JAVABean
public class User {
private String username;
private Integer age;
// getter/setter
// toString
}
@Test
public void test() throws IntrospectionException {
// 获取User Bean信息
final BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
// 属性描述
final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
System.out.println("属性描述: ");
Stream.of(propertyDescriptors).forEach(System.out::println);
// 方法描述
System.out.println("方法描述: ");
for (MethodDescriptor methodDescriptor : beanInfo.getMethodDescriptors()) {
System.out.println(methodDescriptor);
}
// 事件描述
System.out.println("事件描述: ");
for (EventSetDescriptor eventSetDescriptor : beanInfo.getEventSetDescriptors()) {
System.out.println(eventSetDescriptor);
}
}
输出
属性描述:
java.beans.PropertyDescriptor[name=age; propertyType=class java.lang.Integer; readMethod=public java.lang.Integer com.test.User.getAge(); writeMethod=public void com.test.User.setAge(java.lang.Integer)]
java.beans.PropertyDescriptor[name=class; propertyType=class java.lang.Class; readMethod=public final native java.lang.Class java.lang.Object.getClass()]
java.beans.PropertyDescriptor[name=username; propertyType=class java.lang.String; readMethod=public java.lang.String com.test.User.getUsername(); writeMethod=public void com.test.User.setUsername(java.lang.String)]
方法描述:
java.beans.MethodDescriptor[name=getClass; method=public final native java.lang.Class java.lang.Object.getClass()]
java.beans.MethodDescriptor[name=setAge; method=public void com.test.User.setAge(java.lang.Integer)]
java.beans.MethodDescriptor[name=getAge; method=public java.lang.Integer com.test.User.getAge()]
java.beans.MethodDescriptor[name=wait; method=public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException]
java.beans.MethodDescriptor[name=notifyAll; method=public final native void java.lang.Object.notifyAll()]
java.beans.MethodDescriptor[name=notify; method=public final native void java.lang.Object.notify()]
java.beans.MethodDescriptor[name=getUsername; method=public java.lang.String com.test.User.getUsername()]
java.beans.MethodDescriptor[name=wait; method=public final void java.lang.Object.wait() throws java.lang.InterruptedException]
java.beans.MethodDescriptor[name=hashCode; method=public native int java.lang.Object.hashCode()]
java.beans.MethodDescriptor[name=setUsername; method=public void com.test.User.setUsername(java.lang.String)]
java.beans.MethodDescriptor[name=wait; method=public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException]
java.beans.MethodDescriptor[name=equals; method=public boolean java.lang.Object.equals(java.lang.Object)]
java.beans.MethodDescriptor[name=toString; method=public java.lang.String com.test.User.toString()]
// 通过PropertyDescriptor
实现数据和对象绑定
/**
* 数据与对象绑定
*
* @throws IntrospectionException
*/
@Test
public void test1() throws IntrospectionException {
User user = new User();
final BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
Stream.of(beanInfo.getPropertyDescriptors()).forEach(propertyDescriptor -> {
final String name = propertyDescriptor.getName();
try {
if (name.equals("username")) {
propertyDescriptor.getWriteMethod().invoke(user, "张三");
}
if (name.equals("age")) {
propertyDescriptor.getWriteMethod().invoke(user,12);
}
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
});
System.out.println(user);
}
User{username='张三', age=12}
// 反射和内省区别
内省的操作只针对javaBean
,只有符合javaBean
规则的类的成员才可以采用内省API进行操作,而反射一个类的所有成员变量都可以进行反射操作。
操作方式不一样
内省先得到属性描述器然后进行操作,反射则是先得到类的class然后再进行操作