众所周知,被private修饰的变量,只能在本类访问
访问权限 | 本类 | 本包的类 | 子类 | 非子类的外包类 |
---|---|---|---|---|
public | 是 | 是 | 是 | 是 |
protected | 是 | 是 | 是 | 否 |
default | 是 | 是 | 否 | 否 |
private | 是 | 否 | 否 | 否 |
1、public: 所修饰的类、变量、方法,在内外包均具有访问权限;
2、protected: 这种权限是为继承而设计的,protected所修饰的成员,对所有子类是可访问的,但只对同包的类是可访问的,对外包的非子类是不可以访问;
3、包访问权限(default): 只对同包的类具有访问的权限,外包的所有类都不能访问;
4、private: 私有的权限,只对本类的方法可以使用;
定义一个studen类
public class Student {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
}
特意没有age属性的set函数
定义student子类subStudent
public class SubStudent extends Student{
/**
* 子类新增的属性
*/
private String sex;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
在subStudent写mian函数,测试下subStudent能否修改age变量
如上图,ide工具是没有提示setAge函数,因此不能给age赋值
测试能否直接给student实例赋值age属性
如上图,student实例也不能直接赋值,因为定义的student类没有setAge函数
画重点:使用反射骚操作就能解决此问题,上代码
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
SubStudent subStudent = new SubStudent();
subStudent.setSex("可以设置");
subStudent.setName("可以设置");
//subStudent.set
Student student = new Student();
student.setName("可以设置");
//使用反射骚操作就能解决此问题
int newAge = 666; //准备给age赋值的变量
Class<? extends Student> class1 = student.getClass();
Field declaredField = class1.getDeclaredField("age");
declaredField.setAccessible(true);
declaredField.set(student, newAge);
System.out.println("打印反射赋值后的值:" + student.getAge());
}
控制台打印
打印反射赋值后的值:666
总结
此场景主要是作用于一些第三方jar包,没有提供修改字段的权限,但是业务上又需要修改,因此可以使用反射赋值修改