上一节课程提到通过反射获取字段的数据的时候,只能操作public的字段,因为反射调用也要满足调用权限,不过一般的JavaBean对象的私有字段都会提供setter和getter方法来操作字段数据,下面还是看一个例子。
package temp;
public class ClassInfo {
private String fieldOne;
private int fieldTwo;
public ClassInfo() {
}
public String getFieldOne() {
return fieldOne;
}
public void setFieldOne(String fieldOne) {
this.fieldOne = fieldOne;
}
public int getFieldTwo() {
return fieldTwo;
}
public void setFieldTwo(int fieldTwo) {
this.fieldTwo = fieldTwo;
}
}
这一次的对象是一个完全吻合JavaBean规范的简单类。
package temp;
import java.lang.reflect.Method;
public class Reflect {
public static void main(String[] args) throws Exception {
ClassInfo classInfo=new ClassInfo();
System.out.println("fieldOne is:"+classInfo.getFieldOne());
System.out.println("fieldTwo is:"+classInfo.getFieldTwo());
System.out.println("++++++++++++++++++++++++++++++++++++");
//通过setter方法设定字段数据。
Method mothod=ClassInfo.class.getDeclaredMethod("setFieldOne", String.class);
mothod.invoke(classInfo, "FieldOne");
mothod=ClassInfo.class.getDeclaredMethod("setFieldTwo",int.class);
mothod.invoke(classInfo,123);
System.out.println("fieldOne is:"+classInfo.getFieldOne());
System.out.println("fieldTwo is:"+classInfo.getFieldTwo());
System.out.println("++++++++++++++++++++++++++++++++++++");
//通过getter方法获取字段数据。
mothod=ClassInfo.class.getDeclaredMethod("getFieldOne");
String fieldOne=(String) mothod.invoke(classInfo);
mothod=ClassInfo.class.getDeclaredMethod("getFieldTwo");
int fieldTwo=((Integer) mothod.invoke(classInfo)).intValue();
System.out.println("fieldOne is:"+fieldOne);
System.out.println("fieldTwo is:"+fieldTwo);
}
}
执行Reflect将会看到通过反射可以调用字段对应的getter和setter方法操作字段的信息。
需要解释的几点:
1:getDeclaredMethod("setFieldOne", String.class);
这个表示获取名称为setFieldOne,并且包含一个String类型参数的方法(Method).
这个方法的第二个参数是变长参数(Object...)!也就是说可以没有,也可以是多个(很明显,名称相同的重载方法在Java中很常见).
2:mothod.invoke(classInfo,123);
这个表示对classInfo这个实例对象执行mothod对应的方法,并且提供123作为这个方法的参数数据.
同样的这个方法的第二个参数也是变长参数(Object...)!一个方法可以没有参数,也可能有很多个参数,很正常.
如果method对应的方法时候返回值的,那么invoke方法的返回值就是执行method对应方法以后的返回值.
3:通过上面的方法,可以使用反射调用一个Class的任何方法,而一个Class的信息是可以通过第一节教程的内容全部获取到.总结起来就是一句话,可以在运行时任意操控一个对象.
不过如果你要操控的是一个完全的JavaBean对象,那么有更好的方法,那就是使用java.beans.BeanInfo这个类,不过文章就只到这里了,下次再说BeanInfo的使用。
package temp;
public class ClassInfo {
private String fieldOne;
private int fieldTwo;
public ClassInfo() {
}
public String getFieldOne() {
return fieldOne;
}
public void setFieldOne(String fieldOne) {
this.fieldOne = fieldOne;
}
public int getFieldTwo() {
return fieldTwo;
}
public void setFieldTwo(int fieldTwo) {
this.fieldTwo = fieldTwo;
}
}
这一次的对象是一个完全吻合JavaBean规范的简单类。
package temp;
import java.lang.reflect.Method;
public class Reflect {
public static void main(String[] args) throws Exception {
ClassInfo classInfo=new ClassInfo();
System.out.println("fieldOne is:"+classInfo.getFieldOne());
System.out.println("fieldTwo is:"+classInfo.getFieldTwo());
System.out.println("++++++++++++++++++++++++++++++++++++");
//通过setter方法设定字段数据。
Method mothod=ClassInfo.class.getDeclaredMethod("setFieldOne", String.class);
mothod.invoke(classInfo, "FieldOne");
mothod=ClassInfo.class.getDeclaredMethod("setFieldTwo",int.class);
mothod.invoke(classInfo,123);
System.out.println("fieldOne is:"+classInfo.getFieldOne());
System.out.println("fieldTwo is:"+classInfo.getFieldTwo());
System.out.println("++++++++++++++++++++++++++++++++++++");
//通过getter方法获取字段数据。
mothod=ClassInfo.class.getDeclaredMethod("getFieldOne");
String fieldOne=(String) mothod.invoke(classInfo);
mothod=ClassInfo.class.getDeclaredMethod("getFieldTwo");
int fieldTwo=((Integer) mothod.invoke(classInfo)).intValue();
System.out.println("fieldOne is:"+fieldOne);
System.out.println("fieldTwo is:"+fieldTwo);
}
}
执行Reflect将会看到通过反射可以调用字段对应的getter和setter方法操作字段的信息。
需要解释的几点:
1:getDeclaredMethod("setFieldOne", String.class);
这个表示获取名称为setFieldOne,并且包含一个String类型参数的方法(Method).
这个方法的第二个参数是变长参数(Object...)!也就是说可以没有,也可以是多个(很明显,名称相同的重载方法在Java中很常见).
2:mothod.invoke(classInfo,123);
这个表示对classInfo这个实例对象执行mothod对应的方法,并且提供123作为这个方法的参数数据.
同样的这个方法的第二个参数也是变长参数(Object...)!一个方法可以没有参数,也可能有很多个参数,很正常.
如果method对应的方法时候返回值的,那么invoke方法的返回值就是执行method对应方法以后的返回值.
3:通过上面的方法,可以使用反射调用一个Class的任何方法,而一个Class的信息是可以通过第一节教程的内容全部获取到.总结起来就是一句话,可以在运行时任意操控一个对象.
不过如果你要操控的是一个完全的JavaBean对象,那么有更好的方法,那就是使用java.beans.BeanInfo这个类,不过文章就只到这里了,下次再说BeanInfo的使用。