在 Java 中,当存在拒绝访问检查抑制的 SecurityManager 时,Constructor 的 newInstance 方法会起作用,而 Class 的 newInstance 会抛出 SecurityException。下面是一个例子:

import java.lang.reflect.ReflectPermission;
import java.security.Permission;

public class Test {
    public static void main(String[] args) throws Exception {
        System.setSecurityManager(new SecurityManager() {
            @Override
            public void checkPermission(Permission perm) {
                if (perm instanceof ReflectPermission && "suppressAccessChecks".equals(perm.getName())) {
                    throw new SecurityException();
                }
            }
        });

        String.class.getConstructor().newInstance(); // works
        String.class.newInstance(); // throws SecurityException
    }
}

运行它会产生:
Exception in thread "main" java.lang.SecurityException
    at Test$1.checkPermission(Test.java:10)
    at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:125)
    at java.lang.Class$1.run(Class.java:351)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.lang.Class.newInstance0(Class.java:348)
    at java.lang.Class.newInstance(Class.java:325)
    at Test.main(Test.java:16)

Class.newInstance 的 JavaDoc 说它在 SecurityManager 上调用 checkMemberAccess 和 checkPackageAccess,但我不知道为什么它会调用 setAccessible 。这种行为差异有什么理由吗?

我正在使用:
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.5) (ArchLinux-6.b20_1.9.5-1-x86_64)
OpenJDK 64-Bit Server VM (build 17.0-b16, mixed mode)

最佳答案

Class.newInstance() 调用 SecutrityManager.checkMemberAccess(this, Member.PUBLIC) ,默认情况下,它授予所有公共(public)成员的访问权限。 checkPermission() 仅在有问题的成员不是 public 时才被调用(由 checkMemberAccess() )。

因此,您对 checkPermission() 的覆盖不会影响对公共(public)成员的访问。您需要覆盖 checkMemberAccess()

以下是 Class 的 Javadocs 中的相关引用:



SecurityManager :

关于java - 带有 SecurityManager 的 Constructor.newInstance 与 Class.newInstance,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4908986/

10-11 04:41