2010-07-27 14 views
6

Dire se ho il codice seguente, è fondamentale determinare che una condizione sia abbinata e quindi assegnare il valore booleano, quindi eseguire alcuni codici. Quindi lanciare un'eccezione se il valore booleano è falso. Cosa succede se voglio che venga lanciata un'eccezione immediatamente se il valore booleano è falso senza eseguire il resto dei codici? Se metto la seconda istruzione condizionale nella prima, ci saranno dei codici duplicati. Per favore mostrami un modo intelligente per farlo (ho modificato il codice in modo che assomigli ai miei codici reali).Riscrivere un'istruzione condizionale in Java

boolean booleanValue = false; 
Permission value; 

if (someCondition) { 
    value = getPermission_1(); 
    booleanValue = someMethod(value); 
    useValue_1(value); 
} 
else { 
    value = getPermission_2(); 
    booleanValue = anotherMethod(value); 

    useValue_2(value); 
} 

if (!booleanValue) { 
    throw Exception(); 
} 

risposta

7

Come eliminare la variabile booleana? Si potrebbe riscrivere il codice come questo:

if (someCondition) { 
    if (!someMethod()) { 
    throw new Exception(); 
    } 
    some codes... 
} 
else { 
    if (!anotherMethod()) { 
    throw new Exception(); 
    } 
    some codes... 
} 

che sembra più facile ai miei occhi, ma queste cose sono una questione di gusto ...

vantaggio in più: Se l'eccezione finisce in una pila-trace sai qual è stata la condizione perché hai due diverse dichiarazioni di lancio. Questo potrebbe velocizzare un po 'il debug.

+0

Mi piace perché sembra semplice e chiaro. – newguy

4

Invece di

booleanValue = anotherMethod(); 

si dovrebbe semplicemente scrivere

if(!someMethod()) 
    throw new SomeException(); 

Su gettando un Eccezione generica - non lo fanno. Il motivo per cui stai facendo un'eccezione è dire al chiamante che si è verificato qualcosa di eccezionale. È quasi sempre utile dir loro cosa, altrimenti né il chiamante né tu puoi fare qualcosa a riguardo.

+0

Hai ragione, ma quello che ho chiesto è una domanda diversa, ecco perché non ho inserito un nome di escrezione particolare. – newguy

+1

Giusto per precisare che sarebbe se (! SomeMethod()) per mantenere con il codice originale – MadMurf

+0

In realtà il problema è più complicato di quello si prega di dare un'occhiata ai miei codici modificati. – newguy

2

Supponendo che i due some codes... sono diverse, probabilmente vuole fare:

boolean booleanValue = someCondition ? someMethod() : anotherMethod(); 
if(!booleanValue) { 
    throw new Exception(); 
} 

if(someCondition) { 
    // some code 
} else { 
    // some code 
} 

Se sono le stesse della if(someCondition) non è necessario


Se (ipoteticamente) si dispone di un strumento di analisi statica che non consente le espressioni ternarie, è possibile sostituire le prime righe con:

boolean booleanValue; 
if(someCondition) { 
    booleanValue = someMethod(); 
} else { 
    booleanValue = anotherMethod(); 
} 
+0

Questo è uno stile di codice errato per me. Fallirebbe nella fase di checkStyle. – newguy

+2

@newguy Bene, dovrai definire il tuo stile di codice buono; Non ho alcun problema con quel codice –

+0

Il mio progetto utilizza un plug-in di stile di controllo che non consente alcun codice come la prima riga, quindi devo obbedire a questa regola. – newguy

1

La soluzione più ovvia è:

boolean booleanValue = false; 

if (someCondition) { 
    booleanValue = someMethod(); 
    if(booleanValue){ 
     //some codes... 
    } 
} 
else { 
    booleanValue = anotherMethod(); 
    some codes... 
} 

if (!booleanValue) { 
    throw Exception(); 
} 

... ma non mi dispiace ripetere il bit if(!booleanValue) throw Exception();, perché è probabile che un motivo concettualmente diverso che si sta gettando l'eccezione. (Ad esempio, potresti fornire un messaggio di errore migliore nella tua eccezione)

+0

Questa non è la soluzione. Quello che voglio è lanciare l'eccezione immediatamente dopo che il valore booleano è stato assegnato perché non voglio che il resto dei codici sia eseguito. – newguy

+0

@newguy: guarda di nuovo, per favore. Questo è quello che fa. Un po 'non chiaro per i miei gusti però. Preferisco la risposta data da Joel e Nils. –

+0

@newguy: questa soluzione ti dà quello che hai chiesto. Personalmente non mi piace lo stile, ma è probabilmente la soluzione con la differenza meno modificata. – Akusete

1

È tutto molto soggettivo, forse?

boolean booleanValue = aBoolean; 
if (someCondition) { 
    if (!someMethod()) { 
     throw new SomeException(); 
    } 
    some codes... 
} else { 
    if (!anotherMethod()) { 
    throw new AnotherException(); 
    } 
    some other codes... 
} 
1

La soluzione migliore sarebbe ...

if (someCondition) { 
    value = getPermission_1(); 

    if (!someMethod(value)) { 
    throw new SomeException(); 
    } 

    useValue_1(value); 
} 
else { 
    value = getPermission_2(); 

    if (!anotherMethod(value)) { 
    throw new AnotherException(); 
    } 

    useValue_2(value); 
} 

e non si deve guardare su di essa come la duplicazione di codice, perché se si vuole lanciare un'eccezione quindi l'aspettativa è che la ragione per la l'eccezione sarebbe diversa in ogni caso e quindi un'eccezione diversa o un messaggio diverso dovrebbe essere passato in ogni caso.

Presumo che tu voglia sapere quale condizione è stata eseguita e successivamente fallita, perché tutto quello che stai tornando è un booleano dal tuo ... Il metodo chiama il motivo dell'errore probabilmente non sarà evidente in questo scenario.

0

Questo tipo odora ... come in "codice odore". Un valore di ritorno viene tradotto in un'eccezione. Sembra che se il chiamante ha scritto someMethod e anotherMethod, allora la soluzione è di riscrivere quei metodi e lanciare l'eccezione da quei metodi invece di usare un valore di ritorno. Ma questo è solo se il programmatore ha accesso al codice. Se si tratta di una chiamata API di terze parti, suppongo che la traduzione potrebbe dover avvenire.