JavaBean的内省操作

来源:互联网 发布:淘宝牛仔裤质量好的店 编辑:程序博客网 时间:2024/05/23 01:22

1.什么是javaBean?

拥有getter/setter方法。对于gettime,setTime其属性名为time;setCPU则属性名为CPU.即如果属性的第二个字母是小写,则第一个字母是小写。

2.什么是内省?

JDK中提供了对JavaBean进行操作的一些API,这套API就成为内省。内省是java语言对Bean类的属性、事件的一种缺省(默认)处理方法。例如类A中有属性name,我们可以通过getName和setName方法来操作name属性(得到其值或设置新值)。通过getName和setName来访问name属性,这就是默认的规则。通过内省操作,得到javaBean的getter/setter。

3.简单内省操作

通过构造PropertyDescriptor对象来得到JavaBean的对应属性描述,利用该对象的getReadMethod()和getWriteMethod()方法来得到属性的getter/setter方法Method对象,调用Mthod的invoke方法即可得到属性值或设置新值。具体代码如下:

package com.lch.day1;/** * JavaBean * @author Lee * */public class ReflectPoint {private int x;private int y;public ReflectPoint(int x, int y) {super();this.x = x;this.y = y;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}}
package com.lch.day1;import java.beans.PropertyDescriptor;import java.lang.reflect.Method;/** * 测试驱动类 * @author Lee * */public class IntroSpactorTest {public static void main(String[] args) throws Exception {ReflectPoint pt1 = new ReflectPoint(3,6);// 获取ReflectPoint中成员变量x的值String propertyName = "x";// "x" --> "X" --> "getX" --> MethodGetX --> // 使用内省方法// 1.得到javaBean的属性PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass()); // 2.得到属性的getter方法Method methodGetX = pd.getReadMethod();// 3.调用getter方法Object retVal = methodGetX.invoke(pt1);System.out.println(retVal);// 4.得到属性的setter方法Method methodSetX = pd.getWriteMethod();// 5.设置属性值methodSetX.invoke(pt1, 5);// 6.打印新的属性值System.out.println(pt1.getX());}}


后台打印结果如下:

驱动测试类方法重构:

package com.lch.day1;import java.beans.IntrospectionException;import java.beans.PropertyDescriptor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * 测试驱动类 * @author Lee * */public class IntroSpactorTest {public static void main(String[] args) throws Exception {ReflectPoint pt1 = new ReflectPoint(3,6);// 获取ReflectPoint中成员变量x的值String propertyName = "x";// "x" --> "X" --> "getX" --> MethodGetX --> // 使用内省方法Object retVal = getProperty(pt1, propertyName);System.out.println(retVal);Object value = 5;setProperty(pt1, propertyName, obj);// 6.打印新的属性值System.out.println(pt1.getX());}/** * 得到属性值 * @param pt1 * @param propertyName * @return * @throws IntrospectionException * @throws IllegalAccessException * @throws InvocationTargetException */private static Object getProperty(Object pt1, String propertyName)throws IntrospectionException, IllegalAccessException,InvocationTargetException {PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass()); Method methodGetX = pd.getReadMethod();Object retVal = methodGetX.invoke(pt1);return retVal;}/** * 设置新的属性值 * @param pt1 * @param propertyName * @param value * @throws IntrospectionException * @throws IllegalAccessException * @throws InvocationTargetException */private static void setProperty(Object pt1, String propertyName, Object value)throws IntrospectionException, IllegalAccessException,InvocationTargetException {PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass()); Method methodGetX = pd.getWriteMethod();methodGetX.invoke(pt1, value);}}

4.复杂的内省操作

采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的x属性。在程序中把一个类当作JavaBean来看,就是调用IntroSpector.getBeanInfo方法,得到的BeanInfo对象封装了把这个类当作JavaBean看的结果信息。代码如下:

package com.lch.day1;import java.beans.BeanInfo;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * 测试驱动类 * @author Lee * */public class IntroSpactorTest1 {public static void main(String[] args) throws Exception {ReflectPoint pt1 = new ReflectPoint(3,6);// 获取ReflectPoint中成员变量x的值String propertyName = "x";// "x" --> "X" --> "getX" --> MethodGetX --> // 使用内省方法Object retVal = getProperty(pt1, propertyName);System.out.println(retVal);Object value = 5;setProperty(pt1, propertyName, value);// 6.打印新的属性值System.out.println(pt1.getX());}/** * 得到属性值 * @param pt1 * @param propertyName * @return * @throws IntrospectionException * @throws IllegalAccessException * @throws InvocationTargetException */private static Object getProperty(Object pt1, String propertyName)throws IntrospectionException, IllegalAccessException,InvocationTargetException {BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());// 得到Bean的所有属性描述PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();Object retVal = null; for(PropertyDescriptor pd : pds) { // 遍历属性if (pd.getName().equals(propertyName)){ // 判断属性名是否相同Method methodGetX = pd.getReadMethod();     retVal = methodGetX.invoke(pt1); // 调用方法,得到属性值break;}}return retVal;}/** * 设置新的属性值 * @param pt1 * @param propertyName * @param value * @throws IntrospectionException * @throws IllegalAccessException * @throws InvocationTargetException */private static void setProperty(Object pt1, String propertyName, Object value)throws IntrospectionException, IllegalAccessException,InvocationTargetException {BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());// 得到Bean的所有属性描述PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();for(PropertyDescriptor pd : pds) { // 遍历属性if (pd.getName().equals(propertyName)){ // 判断属性名是否相同Method methodSetX = pd.getWriteMethod();methodSetX.invoke(pt1,90); // 调用方法,设置新值break;}}}}

5.比较

复杂的内省操作是先得到BeanInfo class,通过BeanInfo得到所有属性的PropertyDescriptor,再通过循环遍历得到属性名相同的,就可以得到读写方法了。简单的内省操作是通过PropertyDescriptor的构造器得到对应属性的PropertyDescriptor,再操作读写方法。

 

0 0
原创粉丝点击