您的位置:首页 > 编程语言 > Java开发

JavaBean的内省操作

2014-10-12 14:10 218 查看

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,再操作读写方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: