[英]Using 'this' as a parameter to a method call in a constructor
我有一個如下構造函數:
public Agent(){
this.name = "John";
this.id = 9;
this.setTopWorldAgent(this, "Top_World_Agent", true);
}
我在方法調用中得到一個空指針異常。 這似乎是因為我在setTopWorldAgent方法中使用'this'作為參數。 通過刪除此方法調用一切正常。 為什么會這樣? 還有其他人經歷過這個嗎?
您可以將此傳遞給方法,但setTopWorldAgent()不能是抽象的。 您無法在構造函數中進行虛擬調用。
在對象的構造函數中,您可以調用在該對象或基類中定義的方法,但是您不能期望調用由派生類提供的內容,因為派生類的某些部分尚未構造。 如果setTopWorldAgent()是抽象的,我會期望某種編譯器錯誤。
在Java中,您可以使用構造函數和派生類獲得令人驚訝的行為 - 這是一個示例
http://en.wikipedia.org/wiki/Virtual_functions#Java_3
如果您習慣使用C#或C ++,您可能認為調用虛函數是安全的,而不是調用被覆蓋的函數。 在Java中,即使派生類未完全構造,也會進行虛擬調用。
如果這不是正在發生的事情,那么可能是setTopWorldAgent()需要的所有部分都被初始化 - 如果不是,它可能是需要初始化的成員之一。
編輯:以為這是C#
出於好奇,你為什么要把'this'傳遞給同一個班級的成員函數? setTopWorldAgent()可以直接使用'this'。 它看起來不像你的構造函數或setTopWorldAgent()是靜態的,所以我不確定你為什么要傳遞一個它已經有權訪問的成員函數。
除非我遺漏了什么......
為什么setTopWorldAgent
需要this
作為參數? 基於調用,它是一個實例方法,因此它可以引用this
而無需將其作為參數接收。
我想更多的是,為什么你把'this'作為參數傳遞給'this'中的方法?
以下將測試你說的發生在你身上的事情,我沒有遇到麻煩。
public class Test {
public Test() {
this.hi(this);
}
public void hi(Test t) {
System.out.println(t);
}
public static void main(String[] args) throws Exception {
Test t = new Test();
}
}
鑒於setTopWorldAgent似乎是一個實例方法,為什么你還要通過它呢?
this
不是空的,這是肯定的。 它被分配了。
這就是說,有沒有必要通過this
進入方法,它在所有的實例方法自動可用。 如果方法是靜態的,您可能需要將其重構為實例方法。
“這個”永遠不應該是空的。 你確定因此而被拋出異常嗎?
需要注意的是,如果方法是虛擬的,或者調用任何虛方法,則可以在初始化子類的變量之前運行屬於子類的方法。
錯誤必須在其他地方,因為上面的代碼肯定有效,null引用必須是別的。
如果您的代理正在實施ITopWorldAgent,那么您應該實際執行此操作:
Agent agent = new Agent("John", 9);
agent.setTopWorldAgent(agent, "Top_World_Agent", true);
如果沒有,那你為什么要按照自己的方式設置一些東西呢?
我假設setTopWorldAgent方法中的某些東西正在使用一個尚未在構造函數中初始化的值。
Java的規則規定,您不應該將“this”從其構造函數傳遞給另一個方法,原因很簡單,該對象尚未完全構造。 它引用的對象可能處於不一致狀態。 我很驚訝實際的'this'引用是null,但是當它傳遞給setTopWorldAgent時,'this'的某些成員為null,並且該方法因此而拋出異常並不令人驚訝。
通常,只要您不實際訪問任何成員或調用方法(例如,如果要在另一個對象中設置對“this”的引用),您就可以從構造函數中傳遞'this'。
在這種情況下,參數當然是不必要的,因為該方法已經引用了'this'。
很高興你得到了答案。 我想補充說,將'this'作為參數傳遞會導致意外的並發問題。 您基本上提供了可能非線程安全代碼不安全地操縱對象狀態的可能性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.