package com.itheima.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;
public class ReflectTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3, 5);
String propertyName = "x";
Object retVal = getProperty(pt1, propertyName);
System. out.println(retVal);
Object value = 7;
setProperty(pt1, propertyName, value);
System. out.println(pt1.getX());
}
private static void setProperty(Object pt1, String propertyName,
Object value) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds){
if (pd.getName().equals(propertyName)){
Method writeMethod = pd.getWriteMethod();
writeMethod.invoke(pt1,value);
}
}
}
private static Object getProperty(Object pt1, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
Object retVal = null ;
for (PropertyDescriptor pd : pds){
if (pd.getName().equals(propertyName)){
Method readMethod = pd.getReadMethod();
retVal = readMethod.invoke(pt1);
}
}
return retVal;
}
}
4-4 使用BeanUtils工具包操作JavaBean
使用BeanUtils工具包首先要导入jar包。
首先在工程下创建一个lib文件夹-->将beanutils的jar包拷贝到其中-->右击该jar包-->Build Path-->Add to Build Path。
当看到beanutils的jar包变成奶瓶的时候说明jar包已经添加成功。
需要注意的是beanutils工具包依赖于logging包,因此按照上面的方式将commons-logging也添加到工程中。
效果如下:
编写代码,可以发现使用BeanUtils工具包可以很容易实现与上面的代码相同的效果。
package com.itheima.day1;
import org.apache.commons.beanutils.BeanUtils;
public class ReflectTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3, 5);
System. out.println(BeanUtils.getProperty(pt1, "x"));
BeanUtils. setProperty(pt1, "x", "7");
System. out.println(pt1.getX());
}
}
注意:
1-BeanUtils工具类在对对象的属性进行操作的时候,会自动进行类型转换。例如ReflectPoint类中的x属性为int类型,但是设置属性值的时候传入的参数却可以是String类型,这是因为内部发生了自动类型转换。
2-BeanUtils工具类可以对属性进行级联操作,例如Date(java.util.Date)类中有setTime方法,那么也就相当于Date类型对象有一个time属性,BeanUtils就可以对其进行操作。
示例:
ReflectPoint.java
package com.itheima.day1;
import java.util.Date;
public class ReflectPoint {
private int x ;
private int y ;
private Date birthday = new Date();
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;
}
public Date getBirthday() {
return birthday ;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
ReflectTest.java
package com.itheima.day1;
import org.apache.commons.beanutils.BeanUtils;
public class ReflectTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3, 5);
BeanUtils. setProperty(pt1, "birthday.time", "111");
System. out.println(BeanUtils.getProperty(pt1, "birthday.time" ));
//结果:111
}
}
3-PropertyUtils类也可以操作对象的属性,但是与BeanUtils不同的是它不能进行自动类型转换。
例如ReflectPoint类中的x属性为int类型,但是设置属性值的时候传入的参数就不可以是String类型。
示例:
ReflectTest.java
package com.itheima.day1;
import org.apache.commons.beanutils.PropertyUtils;
public class ReflectTest {
public static void main(String[] args) throws Exception {
ReflectPoint pt1 = new ReflectPoint(3, 5);
System. out.println(PropertyUtils.getProperty(pt1, "x"));
PropertyUtils. setProperty(pt1, "x", "7");
System. out.println(pt1.getX());
}
}
就会曝出如下错误:
Exception in thread "main" java.lang.IllegalArgumentException : Cannot invoke com.itheima.day1.ReflectPoint.setX on bean class 'class com.itheima.day1.ReflectPoint' - argument type mismatch - had objects of type "java.lang.String" but expected signature "int"
at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2181)
at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2097)
at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1903)
at org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:2010)
at org.apache.commons.beanutils.PropertyUtils.setProperty(PropertyUtils.java:896)
at com.itheima.day1.ReflectTest.main( ReflectTest.java:12)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0( Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke( Method.java:597)
at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2116)
... 5 more
