今天继续学习了java反射
1.对象的拷贝功能
class People {
private Long id;
private String name;
private Integer age;
public People() {
}
public People(Long id,String name,Integer age) {
this.setId(id);
this.setName(name);
this.setAge(age);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectTest3 {
private static Object copy(Object obj) throws Exception {
Class clazz = obj.getClass();
Constructor cons = clazz.getConstructor(new Class[]{});//得到空的构造方法
Object copyObj = cons.newInstance(new Object[]{});//间接调用空构造方法实例化copyObj
Field[] fields = clazz.getDeclaredFields();//得到源对象的成员变量(该方法可得到私有的成员变量)
for(Field field : fields) {
String filedName = field.getName();
//得到set、get方法
String firstLetter = filedName.substring(0,1).toUpperCase();
String getMethodName = "get"+firstLetter+filedName.substring(1);//得到get方法名称
String setMethodName = "set"+firstLetter+filedName.substring(1);//得带get方法名称
Method getMethod = clazz.getMethod(getMethodName,new Class[]{});
Method setMethod = clazz.getMethod(setMethodName,field.getType());//得到set方法本身
Object res = getMethod.invoke(obj,new Object[]{});//调用源对象的get方法
setMethod.invoke(copyObj,res);
}
return copyObj;
}
public static void main(String[] args) throws Exception {
People p = (People)copy(new People(1L,"张三",20));
System.out.println(p.getId()+";"+p.getName()+";"+p.getAge());
}
}
用getConstructor方法时需要在类People中显示声明一个无参构造方法,尽管在Java中默认会隐式声明一个无参构造方法,
否则会抛出一个NoSuchMethod异常.getDeclaredFields方法可以得到private访问权限的成员变量,但只是只读的,不能
行修改,那怎样可以对私有属性的修改呢?
2.对私有属性的修改
public class PrivateClass {
private String name = "csdn";
public String getName() {
return this.name;
}
}
import java.lang.reflect.Field;
public class PrivateTest {
public static void main(String[] args) throws Exception{
PrivateClass p = new PrivateClass();
Class clazz = p.getClass();
Field f = clazz.getDeclaredField("javaeye");
f.setAccessible(true);//关键代码
f.set(p,"lisi");
System.out.println(p.getName());
}
}
上面这段代码表示将PrivateClass的name属性值改为javaeye,代码的关键在于:
f.setAccessible(true);
它表示可对私有的变量进行访问
3.数组的反射
import java.lang.reflect.Array;
/**
* 数组反射测试
* @author Administrator
*
*/
public class ArrayReflectTest1 {
public static void main(String[] args) throws Exception{
Class clazz = Class.forName("java.lang.String");
Object arrObj = Array.newInstance(clazz,10);//得到数组的实例
Array.set(arrObj,5,"zhangsan");//在数组第5个索引位置设置值zhangsan
String res = (String)Array.get(arrObj,5);//得到第5个索引位置的值
System.out.println(res);//打印此值
}
}
4.多为数组的反射
import java.lang.reflect.Array;
/**
* 多维数组的反射测试
* @author Administrator
*
*/
public class ArrayReflectTest {
public static void main(String[] args) {
int[] i = new int[]{4,6,3};
Object arr = Array.newInstance(Integer.TYPE,i);//得到的是一个三维数组
Object arrObj = Array.get(arr,2);//此时得到的是一个二维数组
arrObj = Array.get(arrObj,3);//此时得到的是一个一维数组
Array.set(arrObj,2,21);
int[][][] arrcast = (int[][][])arr;
System.out.println(arrcast[2][3][2]);
}
} 上述代码中,出现了Integer.TYPE,它不同于Integer.class.Integer.TYPE表示该包装类型对应的原始类型,如Integer对应与int.