2015-11-16 23 views
1

我目前正在使用一個AsyncTask,並在doInBackground方法運行一段代碼,需要處理某些異常。由於doInBackground方法被覆蓋,所以我不能在方法中添加一個throws子句。我已經插入了一個捕獲異常的try-catch方法,但由於我的方法返回一個Summoner對象,我不得不包含return null;語句,並且我發現我的代碼仍在執行該語句。不能添加一個拋出子句重寫的方法,導致我不得不返回null

我對AsyncTask的使用經驗非常有限,所以如果您需要更多信息或者我在此忽略某些內容,請隨時指出。

public class GetSummonerData extends AsyncTask<String, Void, Summoner> 
{ 
    @Override 
    protected void onPreExecute() 
    { 
     Button button = (Button) findViewById(R.id.btnSearch); 
     button.setText("Loading..."); 
    } 

    @Override 
    protected Summoner doInBackground(String... asyncParams) 
    { 
     try 
     { 
      String summonerName = asyncParams[1]; 
      RiotApi api = new RiotApi("api-key"); 
      Map<String, Summoner> summoners = null; 

      //The following line of code will call the API 
      summoners = api.getSummonersByName(Region.valueOf(asyncParams[0]), summonerName); 
      //stage 1 
      return summoners.get(summonerName); 
     } 
     catch (RiotApiException e) 
     { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Summoner result) 
    { 
     //stage 2 
     startNewIntent(result); 
    } 
} 
public void startNewIntent(Summoner summoner) 
{ 
    Intent intent = new Intent(this, ProfileActivity.class); 
    intent.putExtra("summoner", summoner); 
    startActivity(intent); 
} 

在階段1,summoners變量擁有1個召喚者對象。在階段2,onPostExecute的返回結果等於空。爲什麼即使在try塊中有return語句,也會執行返回null?

+0

你想實現什麼? –

+0

我正在尋找一個解釋,爲什麼它仍然執行返回null語句之後,結果已經在方法的早期返回。 –

回答

1

執行return null的原因是因爲在try-catch塊中引發了異常。這會導致try塊的所有剩餘執行被中止(包括return語句)和catch塊來代替執行。

一旦catch塊從return null退出後,它會被執行,因爲執行繼續正常。

1

試試這個簡單的代碼:

public class Class1 { 
public Class1() { 
    super(); 
} 
public String fetchString(int i) { 
    try { 
     int j = 1/i; 
     return "passed"; 
    } 
    catch(Exception ex) { 
     ex.printStackTrace(); 
    } 
    return null; 
} 

public static void main(String[] args) { 
    Class1 class1 = new Class1(); 
    System.out.println(class1.fetchString(1)); 
    System.out.println(class1.fetchString(0)); 
    } 
} 

你會意識到,當異常被拋出,它被捕獲,因此在「嘗試」塊return語句沒有被調用/執行。 (當i = 0時在1/i處引發異常)。

您的代碼也一樣。

關於你的其他觀察,你不能添加任何新的異常,你正在實現的接口的方法。檢查下面的例子。

public interface myinterface 
{ 
    public void foo(); 
} 

現在考慮這個

public class Ximpl implements myinterface 
{ 
    public void foo() throws IOException 
    { 
    } 
} 

現在,如果客戶有一個像

myinterface varx = new Ximpl(); 
    //he can do that 
    varx.foo(); //without putting it in try catch block. (Remember polymorphism)?? 

如果你真的想拋出一個異常,在catch塊,創建運行時異常的實例代碼,不需要聲明。

0

你可以使用這個技巧,將異常封裝在RuntimeException中並重新拋出它。像這樣

try { 
     Files.createDirectories(Paths.get("")); 
    } catch (IOException ex) { 
     throw new RuntimeException(ex); 
    } 

用這種方法你不需要返回null。

您甚至可以創建自己的擴展RuntimeException的異常版本。這樣你就不需要將它添加到方法簽名中,也不會強迫其他人去捕捉它。就像這樣

public class MyValidationException extends RuntimeException { 

    } 
+0

雖然在這種情況下,它作爲一般情況並不是一個好主意。檢查異常存在的原因,這只是繞過它們。 –

相關問題