2014-09-11 67 views
1

我有一个Singleton类,它是通过按需持有者初始化实现的。根据this的文章,它仍然容易受到反射攻击。如何避免使用反射来创建一个新实例

如何防止从java反射来调用私有构造函数并创建新实例?

这是我SingletonTest类:

class SingletonTest{ 
    public SingletonTest(){ 
     System.out.println("before SingletonTest()"); 
     Singleton s1 = Singleton.getSingleton(); 
     Singleton s2 = Singleton.getSingleton(); 

     System.out.printf("s1 Hash: %d\n",System.identityHashCode(s1)); 
     System.out.printf("s2 Hash: %d\n",System.identityHashCode(s2)); 

     Constructor<?> con = Singleton.class.getDeclaredConstructors()[1]; 
     con.setAccessible(true); 

     //System.out.println(con.toString()); 

     try { 
      Singleton s3 = (Singleton) con.newInstance(); 
      System.out.printf("s3 Hash: %d\n",System.identityHashCode(s3)); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 

     System.out.println("after SingletonTest()"); 
    } 

    public static void main(String[] args){ 
     new SingletonTest(); 
    } 
} 

这是我Singleton类:

final public class Singleton { 
    private Singleton(){ 
     System.out.println("Singleton created...!"); 
    } 

    public static Singleton getSingleton(){ 
     return SingletonHolder.INSTANCE; 
    } 

    static class SingletonHolder{ 
      private static final Singleton INSTANCE = new Singleton(); 
    } 

    public void doStuff(){ 
     System.out.println("dostuff...."); 
    } 

} 

输出:

before SingletonTest() 
Singleton created...! 
s1 Hash: 1924489565 
s2 Hash: 1924489565 
Singleton created...! 
s3 Hash: 294316734 
after SingletonTest() 

回答

1

怎么样检查,并抛出异常的构造函数?

private Singleton(){ 
    if(SingletonHolder.INSTANCE !=null) 
     throw new IllegalStateException("Not allowed!"); 
} 

另一种可能性是,用java Enum实现你的singleton模式。

public enum Singleton { 
    INSTANCE; 
    public void doStuff(){...} 

} 
+0

谢谢这是工作:);我尝试了'java.lang.InstantiationException'这不是一个RunTimeException。我读过你可以使用SecurityManager控制它的地方。任何想法呢? – 2014-09-11 08:52:10

+0

@tiriboy如何抛出'InstantiationError'?或者你想它是'RuntimeEx',只是'new RuntimeException()'?或者我没有得到你? – Kent 2014-09-11 08:56:26

+0

是的,它似乎更自我描述。 TNX。 – 2014-09-11 09:00:50

相关问题