2012-10-07 11 views
5

Ich habe das stundenlang angeguckt und konnte nicht an eine Lösung denken; Ich in der Regel behandeln die Validierung dieser Art mit regex aber ich versuche, eine integrierte Lösung für einen Wechsel zu verwenden (natürlich, ich tun dies nicht häufig):Java-Versuch/Fang - Entweder "Rückkehr wird nicht gefunden" oder "Variable wird nicht initialisiert"?

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."); 
    } 
} 

Der Fehler dabei ist, dass die „Rückkehr "wird vom Compiler nicht gefunden, daher erhalte ich einen Kompilierfehler. Wenn ich die "Rückkehr" außerhalb des try/catch setze, muss ich "input2" deklarieren/initialisieren, was den Zweck der Operation vereitelt. Jede Hilfe wird geschätzt ...

+1

Sie fangen die Ausnahme ab, drucken eine Nachricht aus, aber dann fährt die Methode mit dem' catch' Block fort. Der Compiler beklagt sich darüber, dass Sie nicht zurückkommen, wenn der catch Block getroffen wird (nicht alle Pfade zurückgeben.) – birryree

Antwort

0

Sie brauchen etwas von zurückzukehren oder zu werfen (oder nach dem Fang). Gemessen an der Ausgabe an den Benutzer sieht es so aus, als ob Sie das Gleiche noch einmal machen möchten. Rufen Sie die Methode einfach erneut auf und geben Sie das Ergebnis zurück.

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

Verwenden der Rekursion für "erneut versuchen" ist al etwas seltsam; es wird jedes Mal mehr ausstehende Anrufe auf dem Stapel aufbauen. Obwohl es unwahrscheinlich ist, dass der Benutzer eine schlechte Eingabe so oft eingibt, dass ein Stapelüberlauf verursacht wird, wäre eine Schleife sinnvoller. – Wyzard

1

Lassen Sie Ihre Methode eine Ausnahme auslösen oder Nan zurückgeben.

3

Eine Ausnahme im Bereich catch auslösen. Überall dort, wo Sie die promptUserDecimal Methode aufrufen, jede Ausnahme fangen und die Nachricht dort drucken:

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()); 
} 

Dies wäre ein besserer Ansatz sein, weil Sie die promptUserDecimal kümmert sich nur um Umgang mit einem doppelten Wert lesen lassen. Sie müssen versuchen, jede Klasse und Methode für den spezifischen Zweck zu trennen, für den sie entworfen wurde.

+0

+1, aber wenn Sie 'NumberFormatException' sowieso werfen, dann müssen Sie es nicht fangen. Fangen Sie es nicht an erster Stelle, lass 'parseDouble' die Ausnahme werfen. –

+0

@ user1598390 true in der Tat. Antwort aktualisiert –

3

Sie brauchen so etwas wie:

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

Sie konnten den Standardfehlerwert beim Deklarieren der Variablen zuweisen. –

0

Sie können eine Ausnahme in Ihrem Catch-Block werfen. das heißt

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(); 
    } 
} 

Dann wird jedesmal, wenn sie eine ungültige Eingabe geben, können Sie es fangen und zu handhaben, wo Sie die Methode aus aufrufen.

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

Wenn Sie der Benutzer auf „Bitte versuchen Sie es erneut“ wollen, es klingt wie Sie eine Schleife benötigen:

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

Ich habe eine Frage. Dieses Schnipsel kompilieren? –

+0

@PaulVargas, es kompiliert für mich. Sehen Sie einen Fehler in ihm? – Wyzard

+0

OP: I wie diese Lösung für ein unbeaufsichtigtes Skript – user1612272

0

Einige der Lösungen des Compiler Problem lösen wird aufgeführt, aber der erste Schritt ist es, einen Schritt zurück zu gehen und fragen: „Was kann ich in dem Fall tun mag, dass ein Number auftritt?“

Eine Option besteht darin, die Ausnahme zu propagieren, indem die NumberFormatException erneut ausgelöst oder in eine RuntimeException eingeschlossen wird, sodass sie nicht aktiviert wird. Dies bedeutet, dass der aufrufende Code damit umgehen muss, oder dem Benutzer wird ein StackTrace angezeigt. Wenn Sie diese Route gehen, brauchen Sie nicht einmal einen Versuch in Ihrer Methode zu fangen. Sie können einfach "throws NumberFormatException" auf die Methodensignatur deklarieren und lassen Sie es upstream behandelt werden.

Eine weitere Option ist das Zurückgeben von null, indem Sie entweder "return null" als letzte Anweisung in Ihrem catch-Block verwenden oder null als letzte Anweisung in der Methode zurückgeben. Dies ist eine schreckliche Option, da der Anrufcode und/oder der Endbenutzer nicht die benötigten Informationen erhalten, dass "eine Nicht-Nummer als Eingabe eingegeben wurde".

Ich würde mit Option eins gehen und die Ausnahme behandeln, indem ich dem Benutzer sage, dass scan.nextline + "nicht als gültiges Doppel erkannt wird."

Verwandte Themen