2014-09-11 125 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

相關問題