在Java文档中,它提到使用f.setAccessible(true)方法我们可以违反封装的原则.
但是如果我正在编写任何具有完全安全性的类,例如使用私有变量,我怎么能防止它被反射访问?
例如,我有一个具有完整安全实例变量的类:
public final class Immutable {
private final int someVal;
public Immutable(int someVal) {
this.someVal = someVal;
}
public int getVal() {
return someVal;
}
}
Run Code Online (Sandbox Code Playgroud)
但我可以使用这样的反射修改该实例变量:
public class Tester {
public static void main(String[] args)
throws NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException {
Immutable i = new Immutable(10);
// output 10
System.out.println(i.getVal());
Field f = i.getClass().getDeclaredField("someVal");
f.setAccessible(true);
f.set(i, 11);
// output is 11 which implies some value modified
System.out.println(i.getVal());
}
}
Run Code Online (Sandbox Code Playgroud)
在我的代码中,如何防止使用反射更改不可变类?
我读了关于不可变对象的这个问题,并留下了关于不可变对象和最终字段的问题:
为什么我们需要不可变类中的实例变量为final?
例如,考虑这个不可变类:
public final class Immutable
{
private final int someVal;
public Immutable(int someVal)
{
this.someVal= someVal;
}
public int getVal() {
return val;
}
}
Run Code Online (Sandbox Code Playgroud)
如果在上面的代码中没有set方法,并且实例变量只在构造函数中设置,为什么要求将实例变量声明为final?