我看過this
在IB的API中聲明實例變量時使用,但這似乎是一個壞主意。保證在this
已完全構建後保證分配任務?有關係嗎?在java中初始化一個實例變量時使用'this'?
我認爲實例變量是在構造函數之前初始化的,因爲它們可以被構造函數使用。如果使用this
,是否有一些例外情況?
如果它以某種方式起作用,它似乎不是一個好主意 - second
可用於FirstClass
的構造函數嗎?如果是這樣,SecondClass
之前構造FirstClass
?這意味着num
結果是3而i
是10?或者會有運行時錯誤?任何一種方式都有保證嗎?
public class FirstClass {
SecondClass second = new SecondClass(this);
public int i = 3;
FirstClass(){
i = second.DoSomething();
}
}
public class SecondClass{
private int num = 10;
SecondClass(FirstClass first){
num = first.i;
}
public int DoSomething(){
return num;
}
...
}
我想認爲IB有一個非常堅實的開發團隊,並且知道他們在做什麼。你怎麼看:
- 可以用
this
初始化實例變量嗎? - 應該這樣做嗎?
編輯
答案是肯定有保證的結果(現在 - 但閱讀...),但沒有它不應該做的,因爲它容易在不經意間更改代碼可以改變這個'保證'的結果。
我現在知道,構造一個新的對象時(如FirstClass
)的JVM:
- 分配內存給這個類的所有實例變量和它的所有超。
- 初始化所有使用默認值
- 「正確」初始化所有變量在文本順序從最高超開始(即對象),並用這個類完成變量 - 所以
second
被初始化(即構造)之前我被初始化爲3 - 如果這些「正確的」初始化的調用另一個方法或另一種構造,這樣做是前的第一個構造函數被調用 - 所以
second
構造和之前的FirstClass
構造正在運行返回。 - 如果另一個構造是通過實例的初始化調用(如第4項),它經歷了同樣的過程,從項目1(內存分配,初始化等)
之所以這樣做是不好的是, 「保證」結果可以以兩種方式發生變化:
- 如果源代碼順序改變(例如,如果是
i
之前second
初始化構造)的結果將改變。不容易注意到這一點。 - 如果有人將我們的班級(或班級)劃分爲子類,他們可能不會意識到這種微妙的平衡,並可能在覆蓋時改變影響結果的因素。
因此,看起來IB的API遭受了這種美味,我現在必須牢記在心。
感謝埃米爾H公司的回答和他的方向這篇文章最終導致我我的理解之上:http://www.artima.com/designtechniques/initializationP.html - 這是強烈建議閱讀。
同樣感謝Alexander Drobyshevsky在他的回答中提出了非常相似的觀點。
難道你不能簡單地測試一下,看看結果? –
當然,有一次。但是,我怎麼知道它不是隨機的競爭條件,可能會偶爾表現不同?我想知道是否有任何確定性 - 如果是的話,是否可以使用,或者是否應該由於「風格」原因而避免。 – Ben