2013-04-03 208 views
1

使用Java反射,即使通過私有構造函數,也可以實例化類的對象。對於Java反射中的構造函數類的線程安全

public class MyClass 
{ 
    private MyClass(Object p1, String p2) 
    { 
     // Constructor with no modifications to static code 
    } 
} 

人能做到(在相同或其他任何類,異常處理爲了簡化忽略)

public static final Constructor myClass; 

static 
{ 
    myClass = MyClass.class.getConstructor(Object.class, String.class); 
    myClass.setAccessible(true); 
} 

,然後創建的MyClass新實例像

myClass.newInstance(new Object(), "Test"); 

是的以上呼籲newInstance()線程安全,因爲myClass是靜態的?

回答

3

調用Constructor.newInstance()似乎不是嚴格線程安全;至少在我的openjdk-6實現中,我發現一個sun.reflect.NativeConstructorAccessorImpl類有一個字段定義爲private int numInvocations;,稍後在這行代碼:if (++numInvocations > ReflectionFactory.inflationThreshold()) { - 這可能會像預期的那樣行事。
另外,在Constructor類本身中,方法acquireConstructorAccessor()記錄爲「注意,這裏沒有使用同步」。

但是,狡猾的行爲似乎並不會導致整體的意外行爲,只會反覆/不必要地做事情,因此並行調用newInstance()不會導致某些事情被搞砸。

顯然,你仍然可以在事件構造函數中搞砸了什麼。

+0

嗯...... Weird.One會假設newInstance()是與實際構造函數一樣線程安全的。 – PNS 2013-04-03 21:56:28

+0

好吧,我很同意。但是,與直接調用相比,所涉及的代碼量要多得多。 – skirsch 2013-04-04 09:03:19

4

是的,類實例是靜態的,構造函數是線程安全的,只要它沒有對對象的靜態上下文做任何非線程安全的事情。

+0

這也是我的假設。我會澄清這個問題。 +1。 – PNS 2013-04-03 19:02:53