开发中, 难免遇到些私有的属性和方法, 就好比下面的实体一样, 我们该怎么获得她
, 并玩弄于手掌呢?
我们先来个实体瞧瞧, 给你个对象你也new不了, hahaha… 单身wang
public class Student {
private String name;
private int age;
private Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student(){
throw new IllegalAccessError("就不给你创建");
}
private String getName() {
return name == null ? "" : name;
}
private void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
反射步骤
1. 首先我们要找到要操作的对象
Class<?> clz = Class.forName("top.huiger.Student");
- 1
2. 找到对象在哪了, 但是我们还没找到创建的构造方法是不行的, 关于找哪个构造方法, 自己选择, 自己的对象自己找.
clz.getDeclaredConstructor(String.class, int.class);
- 1
3. 那我们来创建她
, 记得上面的找的构造方法是什么, 要匹配上才行.
Object student = constructor.newInstance("张三", 18); // 张三还是如花 看你爱好
- 1
4. 找到对象了, 我们来调用下, 但是公开的和私有的又有区别
- 公开
Method getAge = clz.getMethod("getAge");
System.out.println("--------------" + getAge.invoke(student));
- 1
- 2
- 私有
Method getName = clz.getDeclaredMethod("getName");
getName.setAccessible(true);
String name = (String) getName.invoke(student);
System.out.println("--------------" + name);
- 1
- 2
- 3
- 4
5. 修改属性, 和调用方法类似
// 找到私有属性
Field age = clz.getDeclaredField("age");
age.setAccessible(true);
age.setInt(student, 20); // 修改属性
System.out.println("--------------"+age.get(student));
- 1
- 2
- 3
- 4
- 5
全部演练代码都在这
Class<?> clz = Class.forName("top.huiger.Student");
// 找到带有这个参数的构造方法
Constructor constructor = clz.getDeclaredConstructor(String.class, int.class);
constructor.setAccessible(true);
// 初始化对象
Object student = constructor.newInstance("张三", 18);
System.out.println("--------------"+constructor.toString());
// 找到该私有方法
Method getName = clz.getDeclaredMethod("getName");
getName.setAccessible(true);
String name = (String) getName.invoke(student);
System.out.println("--------------"+name);
// 找到私有属性
Field age = clz.getDeclaredField("age");
age.setAccessible(true);
age.setInt(student, 20); // 修改属性
System.out.println("--------------"+age.get(student));
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
最后输出
--------------private com.dong.wine.Student(java.lang.String,int)
--------------张三
--------------20
- 1
- 2
- 3