如何通过反思防止访问?

时间:2015-03-25 01:39:18

标签: java reflection

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

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

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

public final class Immutable {
    private final int someVal;

    public Immutable(int someVal) {
        this.someVal = someVal;
    }

    public int getVal() {
        return someVal;
    }
}

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

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

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

2 个答案:

答案 0 :(得分:8)

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

找到定义您的政策文件

答案 1 :(得分:4)

扩展SecurityManager类并覆盖此方法以限制反射访问

@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!");
         }
     }