2012-10-07 73 views
5

我一直盯着這個小時,無法想出解決方案;我通常處理這種類型的正則表達式與驗證,但想使用一個變化的內置解決方案(很明顯,我不經常這樣做):Java try/catch - 「找不到返回」或「變量未初始化」?

private static double promptUserDecimal(){ 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter a decimal"); 
    try{ 
     double input2 = Double.parseDouble(scan.nextLine()); 
     return input2; 
    } catch(NumberFormatException e){ 
     System.out.println("Sorry, you provided an invalid option, please try again."); 
    } 
} 

這樣做的錯誤是「迴歸「沒有被編譯器找到,所以我得到一個編譯錯誤。如果我把「返回」放在try/catch之外,我需要聲明/初始化「input2」,這會破壞操作的目的。任何援助表示讚賞...

+1

你捕捉到這個異常,打印出一條消息,但是這個方法仍然繼續來自catch塊。編譯器抱怨說,如果catch塊被擊中,你不會返回路徑返回) – birryree

回答

0

您需要返回或由(或捕撈之後)扔東西。根據你對用戶的輸出來判斷,看起來你只是想再次做同樣的事情。只需再次調用該方法並返回結果。

private static double promptUserDecimal(){ 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter a decimal"); 
    try{ 
     double input2 = Double.parseDouble(scan.nextLine()); 
     return input2; 
    } catch(NumberFormatException e){ 
     System.out.println("Sorry, you provided an invalid option, please try again."); 
     return promptUserDecimal(); 
    } 
} 
+0

使用遞歸「再試一次」是al奇怪;它會每次在堆棧上建立更多未決呼叫。雖然用戶不太可能輸入錯誤的輸入足夠多的時間導致堆棧溢出,但循環會更有意義。 – Wyzard

1

讓你的方法拋出異常或返回南。

3

catch部分拋出異常。無論你調用promptUserDecimal方法,捕捉任何異常,並打印消息有:

public static void main(String[] args) { 

    double d = 0.0; 
    while (double == 0) { 
     try { 
      d = promptUserDecimal(); 
     } catch (NumberFormatException e) { 
      //log the message... 
      d = 0.0; 
     } 
    } 
} 

private static double promptUserDecimal() throws NumberFormatException { 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter a decimal"); 
    return Double.parseDouble(scan.nextLine()); 
} 

,因爲你讓promptUserDecimal只關心處理讀取double值這將是一個更好的辦法。你必須試着去分離每個類和方法,以達到它設計的特定目的。

+0

+1,但是如果你要拋出'NumberFormatException',那麼你不需要捕獲它,不要抓住它,讓'parseDouble'拋出異常。 –

+0

@ user1598390確實如此答案更新 –

3

你需要的東西,如:

double input2; 
try{ 
    //read input2 
}catch(...){ 
    //... log AND assign a value to input2 in case of invalid input 
} 
return input2; 
+0

您可以在聲明變量時指定默認的錯誤值 –

0

您可以在catch塊中拋出異常。即,

private static double promptUserDecimal() throws OopsException { 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter a decimal"); 
    try{ 
     double input2 = Double.parseDouble(scan.nextLine()); 
     return input2; 
    } catch(NumberFormatException e){ 
     System.out.println("Sorry, you provided an invalid option, please try again."); 
     throw new OopsException(); 
    } 
} 

然後,每次他們給一個無效的輸入時間,你可以捕捉它,處理它,你從調用方法。

0
private static double promptUserDecimal(){ 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter a decimal"); 
    double input2 = 0.0; // <-- explicit initialization 
    try{ 
     double input2 = Double.parseDouble(scan.nextLine()); 
    } catch(NumberFormatException e){ 
     System.out.println("Sorry, you provided an invalid option, please try again."); 
    } 
    return input2; 
} 
3

如果你希望用戶「請重試」,這聽起來像你需要一個循環:

private static double promptUserDecimal(){ 
    final Scanner scan = new Scanner(System.in); 

    // Ask for input until we get something valid 
    while (true) { // Terminated by return within 
     System.out.println("Enter a decimal"); 
     try { 
      return Double.parseDouble(scan.nextLine()); 
     } catch(NumberFormatException e){ 
      System.out.println("Sorry, you provided an invalid option, please try again."); 
      // No return, so the loop will run again 
     } 
    } 
} 
+1

我有一個問題,這段代碼編譯爲? –

+0

@PaulVargas,它爲我編譯,你看到一個錯誤嗎? – Wyzard

+0

OP:I就像這個解決方案用於無人蔘與的腳本一樣。 – user1612272

0

少數上市就能解決問題的編譯器解決方案,但第一步是退後一步,問「我想在事件做一個NumberFormatException異常發生什麼?」

一種選擇是通過重新拋出NumberFormatException或將其包裝在RuntimeException中來傳播異常,以使其不受檢查。這意味着調用代碼將不得不處理它,否則用戶將看到一個堆棧跟蹤。如果你走這條路線,你甚至不需要在你的方法中嘗試一下。你可以在方法簽名上聲明「throws NumberFormatException」,並讓它在上流處理。

另一種選擇是通過使用「返回null」作爲catch塊中的最後一條語句或者返回null作爲方法中的最後一條語句來返回null。這是一個糟糕的選擇,因爲調用代碼和/或最終用戶不會獲得他們需要的信息,即「輸入了非數字。」

我會選擇一個,並通過告訴用戶scan.nextline +「不被識別爲有效的雙精度來處理異常。「