2014-10-02 82 views
5

我正在寫一個LoginRequest類的構造函數,它擴展了一個名爲JsobObjectRequest的類(來自Android中的Volley框架,但這與問題完全無關)super()調用必須是構造函數體中的第一條語句

有了這個代碼:

public LoginRequest(String username, String password, Response.Listener<JSONObject> responseListener, Response.ErrorListener errorListener) { 
     Boolean hasCredentials=(username!=null && password!=null); 
     int method=hasCredentials? Method.POST:Request.Method.GET; 
     super(method, API_URL_LOGIN, null, responseListener, errorListener); 

     this.username=username; 
     this.password=password; 

    } 

我得到的錯誤:調用超()必須在構造函數體中的第一個語句

相反,該代碼編譯就好:

public LoginRequest(String username, String password, Response.Listener<JSONObject> responseListener, Response.ErrorListener errorListener) { 
     super((username!=null && password!=null)? Method.POST:Request.Method.GET, API_URL_LOGIN, null, responseListener, errorListener); 

     this.username=username; 
     this.password=password; 

    } 

但是,它不是有效的完全相同的東西嗎? 在這兩種情況下,根據傳遞給子類構造函數的參數值,在調用超級構造函數之前進行一些簡單的計算。爲什麼編譯器不能編譯第一個例子,因爲它可以編譯第二個例子呢?

調用超級構造函數必須先聲明的規範是否比需要的更簡單,還是我錯過了某些東西?

編輯:這被錯誤標記爲Why do this() and super() have to be the first statement in a constructor?的重複。這個問題更具有通用性,並詢問爲什麼super()必須成爲第一個語句。這裏的問題是,爲什麼像我已違背上述要求(並已在這個問題得到滿意的答覆)的一個的情況下

+1

它可能是編譯器相關的?另一個編譯器可能會理解你的代碼並認爲它​​沒問題... – kiwixz 2014-10-02 20:28:39

+2

它不依賴於編譯器。它在JLS中被陳述。 – kraskevich 2014-10-02 20:30:31

+1

「是......比想要的更簡單嗎?」可能,但設計語言以確保事情安全完成並不容易。今年剛剛發佈的Swift已經嘗試了一套更復雜的規則,但我還不知道它有多好或多壞,或者它對你的特定情況有什麼幫助。 – ajb 2014-10-02 20:36:29

回答

9

Java強制呼叫到super(明確或不)必須是第一語句在構造函數中。這是爲了防止在初始化對象的超類部分之前初始化對象的子類部分。

就你而言,除了本地「微不足道的計算」之外,你什麼也不做,因此所有事情都考慮在內,那就沒問題。但是,Java的編譯器並沒有去確定在調用super之前的語句是否實際進行初始化。它只是不允許在super()之前的所有陳述。

+3

我明白了,謝謝。令人驚訝的是編譯器負責檢測無法訪問的代碼等內容,但無法檢查構造函數中的代碼是否可以執行實際的初始化。 – matteo 2014-10-02 21:03:12

+2

它將能夠檢查這樣的事情。但是,編譯期間可能需要太多時間(猜測)。 – rgettman 2014-10-02 21:08:15

+0

什麼意思是對象的子類部分 – Rico 2014-10-02 21:18:03

相關問題