[英]Using 'this' when initializing an instance variable in java?
我在IB的API中聲明一個實例變量時已經看過this
,但這似乎是一個壞主意。 被分配工作后,發生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
被初始化(即構造)。 FirstClass
之前構造並返回second
構造函數。 這樣做的原因很糟糕,“保證”結果可以通過兩種方式改變:
second
之前初始化i
),結果將會改變。 很容易不注意到這一點。 因此看起來IB的API會受到這種美味的影響,我現在必須牢記這一點。
感謝Emil H的回答和他對本文的指導,這最終促使我理解上述內容: http : //www.artima.com/designtechniques/initializationP.html - 強烈推薦閱讀。
還要感謝Alexander Drobyshevsky在答案中提出了非常相似的觀點。
當然,有時你必須使用它,例如當通過構造函數給出的變量被調用為與實例變量相同時:
int count;
public Test(int count){
this.count = count;
}
是的, this
(在內部是構造中對象的“指針”)可以在構造函數中使用。
一個愚蠢的例子可能是一個自我引用的類
class MySelf {
Myself _me;
public MySelf() { _me = this; }
}
還有更現實的例子。 想象一下,您希望一個類表示一個數學圖,您將使用連接到自身的單個元素進行初始化。
有趣的問題。 在您描述的情況下,當您調用new FirstClass()
,類加載器會查找該類並在未加載它時加載它。 然后它似乎創建了一個FirstClass
實例,其中所有字段都有其默認值,例如,second為null,i為0。
然后是類加載器加載SecondClass
。 創建並初始化SecondClass
的實例,將num
字段設置為10.然后構造函數調用傳入FirstClass
實例(字段具有已初始化到該點的值)。 因此,在構造函數中, SecondClass
中num
的值將設置為0。
在SecondClass
構造函數完成后,將對象get分配給FirstClass
的second
字段(仍在初始化)。 之后i
初始化為3.現在調用FirstClass
的構造函數,並為i分配DoSomething()
的返回值,在本例中為0。
如需進一步參考,請查看: http : //www.artima.com/designtechniques/initializationP.html它給出了對象初始化的描述。
TL; DR所以回答你的問題:
this
可以在初始化實例變量時使用。 這有兩種可能的Java變化; 首先,是您希望引用全局變量(來自外部范圍)。 例如:
class First {
private int x;
public void setX(int x) {
this.x = x; // outer x is equal to the parameter
}
}
另一個用途,是引用當前對象的構造函數。 例如:
public Color {
private int red, green, blue;
public void Color(int r, int g, int b) {
red = red;
green = g;
blue = b;
}
public void setColor(int r, g, b) {
this(r,g,b);
}
}
通過使用3個參數調用此(1,2,3)來告訴編譯器您希望引用帶有3個參數的構造函數。
希望有所幫助!
起初,這是一個糟糕的方式。 您必須避免使用這些結構:使用未完全初始化的變量。 有時候使用“模板方法”設計模式可能會有所幫助。
正是在你的例子中,在這種情況下,在執行FirstClass構造函數之后,i = 0的結果值; 它取決於FirstClass中i的賦值順序。 如果您通過下一個方式更改分配順序:
public int i = 3;
SecondClass second = new SecondClass(this); // just order changed
在FirstClass構造函數執行完后,你得到答案i = 3。
this - 僅引用當前類實例。 它已經存在於您的類實例變量開始初始化時。 首先,所有變量都有其默認值(object為null,int為0等)。 在第二個初始化所有簡單的賦值,如“int i = 3”,之后執行當前類的超級構造函數,最后執行當前類的構造函數。 簡單變量按類中的順序初始化為up,但是你不應該依賴它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.