參考我的earlier question on incompletely constructed objects,我有第二個問題。正如Jon Skeet指出的那樣,在構造函數的最後有一個隱含的內存屏障,確保所有線程都可以看到final
字段。但是如果一個構造函數調用另一個構造函數呢?在他們每個人的結尾有沒有這樣的記憶障礙,或者只有在最初被召喚的那個人的結尾?也就是說,當「錯誤」的解決方案是:鏈接構造函數時JVM的隱式內存障礙如何表現?
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
和正確的人會是一個工廠方法版本:
public class SafeListener {
private final EventListener listener;
private SafeListener() {
listener = new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
}
}
public static SafeListener newInstance(EventSource source) {
SafeListener safe = new SafeListener();
source.registerListener(safe.listener);
return safe;
}
}
將在以下工作過,或沒有?
public class MyListener {
private final EventListener listener;
private MyListener() {
listener = new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
}
}
public MyListener(EventSource source) {
this();
source.register(listener);
}
}
更新:問題的關鍵是this()
保證實際呼叫上面的私有構造函數(在這種情況下會有阻擋,其中預期,一切都將是安全的),或者是有可能私有構造函數將內嵌作爲優化來保存一個內存屏障(在這種情況下,直到公共構造函數結束時纔會有屏障)?
this()
的規則是否在某處準確定義?如果沒有,那麼我認爲我們必須假設允許內聯鏈式構造函數,並且可能有一些JVM或者甚至可以使用它。
這是用權威參考備份的唯一答案。 (以下是參考文獻的實際鏈接:http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html)。我唯一想知道的是,什麼*凍結*的意思在任何地方都沒有解釋過(或者至少我沒有找到它)。 – 2012-04-24 17:28:17
我有同樣的問題,一個非正式的描述是在(http://www.cs.umd.edu/~pugh/java/memoryModel/CommunityReview.pdf),更正式的定義可以在(http:// www.cs.umd.edu/~pugh/java/memoryModel/newFinal.pdf) – 2012-04-26 10:29:34