2011-09-05 8 views
7

Sto provando a verificare se il valore passato da un utente è valido o meno. Ecco il codice che ho scritto.Utilizzo delle eccezioni per convalidare gli ingressi

enum Media_Delivery { 
    Streaming, Progressive 
} 

public class TestMain { 
    public static void main(String[] args) { 
     String medi_delivery = "streaming"; 
     try { 
      Media_Delivery.valueOf("streaming"); 
     } catch (IllegalArgumentException e) { 
      System.out.print(e); 
     } 

    } 

} 

Ora, nel codice di cui sopra, se la stringa passata non è withing enum quotata allora tiri IllegalArgumentException che è ovvio.

Ma la mia domanda è: è questo il modo corretto di convalidare? Poiché stiamo utilizzando il meccanismo di eccezione di Java per la convalida.

Qualcuno può suggerire un'idea migliore o quello che ho codificato sopra di sé è l'opzione migliore?

----- EDIT --------

Un altro caso che ho voluto discutere:



    public class TestMain { 
      public static void main(String[] args) { 
       String inputPassed = "2a"; 
       try { 
        Integer.parseInt(inputPassed); 
       } catch (NumberFormatException nfe) { 
        throw new SomeUserDefinedException("Please enter only numeric values"); 
       } 

      } 

Quindi questa è una buona idea? O dovrebbe esserci il nostro meccanismo di analisi?

+1

Di solito è considerato cattiva pratica di "code verso eccezioni", in altre parole con le eccezioni di determinare la logica. Dai un'occhiata a ciò che @Chris ha suggerito. –

risposta

1

Direi che dipende.

Se l'input proviene da elementi della GUI come combobox o altro, dove i valori enum sono gli unici da scegliere, l'approccio è corretto. Qui un valore diverso sarebbe davvero un'eccezione.

Tuttavia, se si sta creando un'app per console o un file di testo con la possibilità di digitare qualcosa, il risultato sarà diverso, quindi i valori di enumerazione non dovrebbero essere considerati come un'eccezione. Dovresti usare il solito se-else o casi con questo approccio.

Generalmente: utilizzare le eccezioni solo per casi eccezionali e non per qualcosa che è realmente piacevole accadere.

2

Di solito è consigliabile non rilevare o lanciare espressioni deselezionate (IllegalArgumentException è un RuntimeException che conta come "deselezionato"). Vedi the Java Tutorials - Exceptions per maggiori dettagli. Se puoi evitarlo, prova a riscrivere il codice in modo tale che non sia necessaria un'eccezione di runtime. Questo è un problema controverso, ma le eccezioni di runtime esistono per una ragione: aiutano il programmatore a identificare i bug. Se li prendi, il bug non viene corretto, viene solo evitato. Prova a usare una dichiarazione if-else?

Secondo the API, "il nome deve corrispondere esattamente a un identificatore utilizzato per dichiarare una costante enum." Credo che questo significhi che il parametro sia case-sensitive. Inoltre, il tipo restituito del metodo valueOf è un tipo, non void, quindi non è possibile avere quell'istruzione nel blocco try. I blocchi try devono contenere comandi o metodi void, ad esempio int x = 3; o System.out.println(3); o qualcosa del genere.

-------- ------- EDIT

OP, in risposta al tuo commento:

Come altri qui hanno detto, dipende da quello che stai cercando realizzare. Presumo che dal momento che hai la linea Media_Delivery.valueOf("streaming"); nel blocco try, stai provando a vedere se "streaming" è uguale a una delle costanti enum?In tal caso, non avrebbe bisogno di un'istruzione if-else, si potrebbe semplicemente scrivere

boolean result = medi_delivery.equals(Media_Delivery.Streaming.name()) || 
    medi_delivery.equals(Media_Delivery.Progressive.name()); 
System.out.println(result); 

O meglio ancora, se non si desidera avere più || condizioni, provare una dichiarazione switch che cicli attraverso ogni costante enum, testando l'uguaglianza della stringa data.

-Chris

PS: sulla convenzione di denominazione, le costanti enum sono implicitamente static final, è pratica comune dichiarare loro in tutte le protezioni, come STREAMING e PROGRESSIVE (the Java Tutorials - Enums).

+0

Eh? Puoi ignorare gli oggetti restituiti all'interno di un blocco catch try proprio come puoi in qualsiasi altra parte del codice. Che sia o meno una buona idea è un argomento separato e uno che dipenderà da ciò che il programmatore sta cercando di realizzare. – user439407

+0

Quindi testSubject528491 come faccio a completare l'attività sopra con if-else? Potete per favore inserire qualche codice di esempio. –

+1

Grazie mille Chris per il tuo suggerimento e la risposta. –

1

Non c'è un modo unico "vero" per convalidare, quello che hai sarebbe certamente il modo in cui avrei convalidare, ma ci sono altri modi (ad esempio si potrebbe mettere tutti i valori stringa validi di l'enumerazione in un HashSet e quindi controlla contro quel set per vedere se è valido, probabilmente è quello che fa il metodo valueOf)

Ora, se l'approccio sopra è "migliore" o meno, anche questo deve essere piuttosto soggettivo. Se si eseguono le convalide in un ciclo e si desidera rifiutare tutto ciò che contiene dati non validi, l'approccio delle eccezioni è probabilmente il migliore. Se si vogliono contrassegnare tutti gli elementi inappropriati allora l'approccio si avvicina a ... l'HashSet sarà probabilmente più veloce se ci sono molti dati problematici in quanto non si dovranno generare molti nuovi oggetti di eccezione, ma anche la differenza in le prestazioni saranno piuttosto trascurabili.

+0

'performance' e' usa o non usi l'eccezione qui' sono due argomenti molto separati;) – dantuch

8

Eccezioni devono essere utilizzate per condizioni eccezionali; cose che non ti aspetti accadano. Convalidare l'input non è molto eccezionale.

Josh Bloch lo descrive in particolare nel suo libro "Effective Java" che IMHO è qualcosa che ogni programmatore Java dovrebbe avere.

EDIT: E questo è in realtà una buona risposta a come affrontare il problema:

Check valid enum values before using enum