如何通过反思防止访问?

在Java文档中,它提到使用f.setAccessible(true)方法我们可以违反封装的原则。

但是,如果我正在编写任何具有完全安全性的类,例如使用私有变量,我怎样才能防止它被reflection访问?

例如,我有一个具有完整安全实例变量的类:

 public final class Immutable { private final int someVal; public Immutable(int someVal) { this.someVal = someVal; } public int getVal() { return someVal; } } 

但我可以使用这样的reflection修改该实例变量:

 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()); } } 

在我的代码中,如何防止使用reflection更改不可变类?

JVM内置了安全机制,允许您通过Java安全策略文件定义代码限制。 Java安全管理器使用Java安全策略文件来强制授予对类授予的一组权限。 权限允许在JVM的该实例中运行的指定类允许或不允许某些运行时操作。 如果启用Java安全管理器但未指定安全策略文件,则Java安全管理器将使用$ JAVA_HOME / jre / lib / security目录中java.security和java.policy文件中定义的缺省安全策略。 可以在http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html找到定义策略文件的位置。

扩展SecurityManager类并重写此方法以限制reflection访问

 @Override public void checkPackageAccess(String pkg){ // don't allow the use of the reflection package if(pkg.equals("java.lang.reflect")){ throw new SecurityException("Reflection is not allowed!"); } }