2012-10-07 9 views
5

Sono stato a fissare questo per ore e non riesco a pensare a una soluzione; Io di solito gestire la convalida di questo tipo con espressioni regolari, ma sto cercando di utilizzare una soluzione integrata per un cambiamento (ovviamente, non faccio questo di frequente):Java try/catch: "return non viene trovato" o "variable non è inizializzato"?

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

L'errore di questo è che il "ritorno "non viene trovato dal compilatore, quindi ricevo un errore di compilazione. Se metto il "ritorno" al di fuori del try/catch ho bisogno di dichiarare/inizializzare "input2" che vanifica lo scopo dell'operazione. Qualsiasi assistenza è apprezzata ...

+1

Si cattura l'eccezione, si stampa un messaggio, ma il metodo continua ancora dal blocco' catch'. Il compilatore si lamenta del fatto che non si restituisce se viene colpito il blocco catch (non tutto ritorno dei percorsi) – birryree

risposta

0

È necessario restituire o gettare qualcosa da (o dopo la cattura). A giudicare dal tuo output per l'utente, sembra che tu voglia solo fare di nuovo la stessa cosa. Basta chiamare di nuovo il metodo e restituire il risultato.

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

Utilizzare la ricorsione per "riprovare" è tutto è strano; accumulerà più chiamate in sospeso nello stack ogni volta. Anche se è improbabile che l'utente inserisca un input errato un numero sufficiente di volte per causare un overflow dello stack, un loop avrebbe più senso. – Wyzard

1

Lascia che il tuo metodo generi un'eccezione o restituisca nan.

3

Eliminare un'eccezione nella sezione catch. Ovunque si chiama il metodo promptUserDecimal, catturare qualsiasi eccezione e stampare il messaggio là:

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

Questo sarebbe un approccio migliore, perché si lascia che i promptUserDecimal preoccupa solo di gestire la lettura di un valore doppio. Devi cercare di separare ogni classe e metodo per lo scopo specifico per il quale è stato progettato.

+0

+1 ma se si sta per lanciare 'NumberFormatException' comunque, non è necessario catturarlo.Non catturarlo in primo luogo, lasciare' parseDouble' lanciare l'eccezione. –

+0

@ user1598390 Sì. Risposta aggiornata –

3

avete bisogno di qualcosa di simile:

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

È possibile assegnare il valore di errore predefinito quando si dichiara la variabile –

0

È possibile generare un'eccezione all'interno del vostro blocco catch. vale a dire,

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

Poi, ogni volta che danno un input non valido, si può prendere e gestire la cosa in cui si chiama il metodo da.

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

Se si desidera che l'utente "riprova", suona come avete bisogno di un ciclo:

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

Ho una domanda Questo snippet è compilato? –

+0

@PaulVargas, viene compilato per me .Viene visualizzato un errore? – Wyzard

+0

OP: I come questa soluzione per uno script non presidiato – user1612272

0

Alcune delle soluzioni elencate risolverà il problema del compilatore, ma il primo passo è quello di fare un passo indietro e chiedere "che cosa voglio fare nel caso in cui si verifichi un NumberFormatException?"

Un'opzione consiste nel propagare l'eccezione rilanciando la NumberFormatException o inserendola in una RuntimeException in modo che rimanga deselezionata. Ciò significa che il codice chiamante dovrà gestirlo, o l'utente verrà presentato con uno stacktrace. Se segui questa strada non hai nemmeno bisogno di un try catch nel tuo metodo. Puoi semplicemente dichiarare "lancia NumberFormatException" sulla firma del metodo e lasciarlo gestire sul flusso.

Un'altra opzione è restituire null, utilizzando "return null" come ultima istruzione nel blocco catch o restituendo null come ultima istruzione all'interno del metodo. Questa è un'opzione terribile perché chiamare codice e/o utente finale non otterrà le informazioni di cui hanno bisogno, che "un non-numero è stato inserito come input".

Vorrei andare con l'opzione uno, e gestire l'eccezione dicendo all'utente che scan.nextline + "non è riconosciuto come un doppio valido."

Problemi correlati