1. 什么是内省?
内省是指计算机程序在运行时(Run time)检查对象(Object)类型的一种能力,通常也可以称作运行时类型检查。
不应该将内省和反射混淆。相对于内省,反射更进一步,是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。
2. java中的内省机制
内省(Introspector) 是对 JavaBean 类属性、事件的一种缺省处理方法。内省机制是通过反射来实现的。
java Reflect 是在运行时状态将java类分别映射成不同java类(Field,Method,Contructor,Annoation,..)可以动态的获取所有的属性以及动态调用任意一个类行为即方法。
缺省,即系统默认状态,属性默认值。
JavaBean是一种特殊的Java类,主要用于存储数据信息用于传递。在bean中成员变量为private,set和get方法根据变量名按一定规则生成。
3. 内省的具体实现
通过BeanInfo这个类就可以获取到类中的方法和属性,具体的可以参考JDK API文档
java.beans.Introspector(内省者),java.beans.PropertyDescriptor(属性描述器),java.beans.MethodDescriptor(方法描述器)
简单实现可自行重构方法
方法一
得到javabean具体属性值
// 创建bean对象
TestBean bean = new TestBean(1,"lin");
//设置所要得到的bean属性名称
String propertyName = "id";
// 返回值
Object retVal = null;
//通过Introspector类获得BeanInfo
try {
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] props = beanInfo.getPropertyDescriptors();
// 便利得到指定变量并进行操作
for(PropertyDescriptor prop:props) {
// prop.getName()得到的值为Id为合成方法名的名称 用equals方法比对原名称
if(prop.getName().equals(propertyName)) {
Method method = prop.getReadMethod();
retVal = method.invoke(bean);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
设置javabean具体属性值
// 创建bean对象
Object bean = new TestBean(1,"lin");
//设置所要得到的bean属性名称
String propertyName = "id";
Object retVal = null;
retVal = getProperty(bean, propertyName, retVal);
System.out.println(retVal);
//设置传入参数类型得与bean属性匹配 否则报错参数不匹配java.lang.IllegalArgumentException: argument type mismatch
Object setVal = 2; //这里为int型装箱为Integer
try {
//通过Introspector类获得BeanInfo
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] props = beanInfo.getPropertyDescriptors();
// 便利得到指定变量并进行操作
for(PropertyDescriptor prop:props) {
// prop.getName()得到的值为Id为合成方法名的名称 用equals方法比对原名称
if(prop.getName().equals(propertyName)) {
Method method = prop.getWriteMethod();
method.invoke(bean,setVal);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
方法二(Easily)
获取属性值
try {
ropertyDescriptor propDesc = new PropertyDescriptor(propertyName, bean.getClass());
Method getMethod = propDesc.getReadMethod();
retVal = getMethod.invoke(bean);
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
设置属性值
try {
PropertyDescriptor propDesc = new PropertyDescriptor(propertyName, bean.getClass());
Method setMethod = propDesc.getWriteMethod();
retVal = setMethod.invoke(bean,setVal);
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
至此引出一个Apache 开源的commons-beanutils.jar 功能强大,简单,该包依赖commons.logging.jar日志jar
jar包地址:http://commons.apache.org/proper/commons-beanutils/
使用详见官方API
4. 总结:
内省(Introspector) 是对 JavaBean 类属性、事件的一种缺省处理方法。内省机制是通过反射来实现的。java Reflect 是在运行时状态将java类分别映射成不同java类(Field,Method,Contructor,Annoation,..)可以动态的获取所有的属性以及动态调用任意一个类行为即方法。