通过反射不仅能调用公开的方法,同样还能调用私有的方法,只需在method或者field中设置setAccessible(true)就可以破坏对象的私有属性,达到获取并赋值的结果。
1 /** 2 * 调用私有方法和静态方法 3 * 为私有属性赋值 4 */ 5 6 @Test 7 public void TestConstant() { 8 try { 9 Class<?> clazz = Class.forName("basic.reflect.Person"); 10 Constructor<?> constructor = clazz.getConstructor(new Class[] {}); 11 Object instance = constructor.newInstance(new Object[] {}); 12 Method method = clazz.getDeclaredMethod("setName", new Class[] { String.class }); 13 Method staticMethod = clazz.getDeclaredMethod("printPerson", new Class[] {}); 14 staticMethod.setAccessible(true);// 如果想调用私有方法,必须设置这个属性为true,暴力调用 15 staticMethod.invoke(null, null);// 调用静态方法,不用传入对象,直接调用,如果有形参为形参赋值,没有就null 16 method.invoke(instance, new Object[] { "李四" }); 17 System.out.println(instance); 18 19 Field field = clazz.getDeclaredField("name");// 获取属性 20 field.setAccessible(true);// 设置属性能够被修改 21 field.set(instance, "张三");// 为属性赋值 22 System.out.println(instance); 23 24 } catch (Exception e) { 25 // TODO Auto-generated catch block 26 e.printStackTrace(); 27 } 28 29 }
拷贝对象:通过反射拷贝对象算是对反射的一种运用,可以帮助学习反射的方法。
拷贝对象的意思就是将一个对象的值通过反射机制传给另一个对象。
1 /** 2 * 拷贝对象 3 */ 4 @Test 5 public void testCopyObject() { 6 Person person=new Person(); 7 person.setName("李四"); 8 person.setId(1); 9 person.setAddress("郑州"); 10 try { 11 Class<? extends Object> clazz=person.getClass(); 12 Constructor<? extends Object> constructor=clazz.getConstructor(new Class[] {});//获取无参构造器 13 Object instance=constructor.newInstance(new Object[] {});//声明对象 14 Field[] fields=clazz.getDeclaredFields(); 15 for(Field f:fields) { 16 String fname=f.getName();//获取属性名字 17 Class<?> type=f.getType();//获取属性类型 18 String setName="set"+fname.substring(0,1).toUpperCase()+fname.substring(1);//找到set方法 19 String getName="get"+fname.substring(0,1).toUpperCase()+fname.substring(1);//找到get方法 20 21 Method getMethod=clazz.getDeclaredMethod(getName, null);//获取get方法 22 Object gResult=getMethod.invoke(person, null);//调用get方法并获取返回值 23 Method setMethod=clazz.getDeclaredMethod(setName, new Class[] {getMethod.getReturnType()});//获取set方法 24 setMethod.invoke(instance, new Object[] {gResult});//调用set方法并赋值 25 26 } 27 System.out.println(instance); 28 } catch (Exception e) { 29 // TODO Auto-generated catch block 30 e.printStackTrace(); 31 } 32 33 34 }