2010-04-16 50 views
6

假设我在我的应用程序的外部库中有一个单例类。但我仍然可以使用反射来创建该特定类的实例。像这样Java反射框架和安全

Class clas = Class.forName(Private.class.getName()); 

    for(Constructor c : clas.getDeclaredConstructors()){ 
     c.setAccessible(true); 
     Private p = (Private) c.newInstance(); 
     System.out.println(p); 
    } 

我该如何限制? 。

由于 Ĵ

+0

啊单身的痛苦.. – 2010-04-16 11:54:23

+2

参见:http://stackoverflow.com/questions/2481862/how-to-limit-setaccessible-to-only-legitimate-uses – polygenelubricants 2010-04-16 11:57:06

回答

6

通过使用SecurityManager和控制步骤,控制ReflectPermission("suppressAccessChecks")example)。

虽然安全管理器会影响性能,但很少在服务器端使用。

+0

[多大性能影响?](http://stackoverflow.com/questions/14903423/security-manager-rarely-used-on-server) – 2013-02-15 21:17:05

0

长话短说:你不能

任何构造函数public,private和private都可以通过反射来访问,并且可以用来实例化一个新对象。

您需要使用其他方法,例如SecurityManager

0

我不认为你可以限制这一点。

使用反射访问其他人的私人部分显然是一种危险/可疑的做法(snicker),但有时需要使用各种类型的工具和应用程序。

1

如果你谈论尤其单身:这是一个原因,最好的方式来实现它们是通过枚举:

public enum YourSingleton { 
    INSTANCE; 
    // methods go here 
} 

如果你在谈论一般使用setAccessible():如果代码是由你不信任的人写的,不要做这样的诡计,你不应该运行它(或运行在沙箱中)。在开发人员中,公共/私人应该被视为有关如何使用代码的元信息 - 而不是安全功能。

0

AFAIK这是一种元编程,因此需要检查不同的抽象层。从Javadoc我想,你应该使用SecurityManager来执行你想要的行为:setAccessible()。 一般恕我直言,你应该真的知道你在做什么,当你是元编程和改变访问应该真的有很好的理由要做。

0

你可以这样做。

private static final Private INSTANCE = new Private(); 
    private Private() { 
     if(INSTANCE !=null) 
      throw new IllegalStateException("Already instantiated"); 
    } 
    public static Private getInstance() { 
      return INSTANCE; 
     } 
+0

单身人士在第三方罐子的范围之外。所以这根本无济于事。这种技术是不安全的,因为你可以通过反射来改变它(正如问题中提到的那样)。 – whiskeysierra 2010-04-17 17:27:30