2012-10-30 20 views
1

爲什麼java不會阻止你實例化任何單例類對象?爲什麼我可以使用反射創建一個以上的單例實例?

我試圖創建太虛類

java.lang.Void 

的對象我寫了這個代碼來創建兩個實例

try{ 
    Class clazz = Void.class; 
    Constructor cons = clazz.getDeclaredConstructor(); 
    cons.setAccessible(true); 
    Void s2 = (Void) cons.newInstance(); 
    System.out.println(s2); 
    Void s3 = (Void) cons.newInstance(); 
    System.out.println(s3); 

}catch (Exception e) { 
    e.printStackTrace(); 
} 

任何人都可以解釋 - 爲什麼這是允許在java嗎?

+2

使用Singleton模式並不能保存您通過'Reflection'創建的實例。你可以使用'Reflection'來訪問私人領域和構造函數。所以,它不是'Java'允許的。它的Reflection API違反了規則。 –

+0

'Void'不是單例,順便說一下,它的意圖是有_no_實例,因爲它的目的僅僅是作爲'Void.TYPE'的容器,符合其他基本類型'Class'對象'int'的Integer.TYPE等)。 –

回答

5

使用這樣的反射可以避開正常的保護機制,並執行像調用私有構造函數和通常無法訪問的方法之類的東西。 Java不允許你在沒有調用setAccessible的情況下通過私有構造函數實例化一個類 - 實質上這意味着「我知道我不應該這樣做,但是......」

如果你需要運行不可信代碼,那麼您可以使用SecurityManager機制來禁止這種「違規」。

2

因爲Java無法知道您希望該類用作單例。如果你想要這樣一個類,使用枚舉。

相關問題