2012-09-23 3 views
25

Nelle pagine come http://en.wikipedia.org/wiki/?: l'operatore ternario/condizionale ?: sembra essere utilizzato per assegnazioni condizionali. Ho provato ad usarlo per la chiamata al metodo, in questo modo:È possibile utilizzare l'operatore ternario/condizionale di Java (? :) per chiamare i metodi anziché assegnare valori?

(condition) ? doThis() : doThat(); 

Entrambi i metodi restituiscono void. Java mi dice che non è una dichiarazione.

Quindi, immagino che non sia possibile chiamare il metodo condizionale ... o posso?

+14

No, non così. Basta usare un "se" come una persona normale. –

+1

Credo che l'operatore ternario debba assegnare valori a un'istanza di un tipo, con un controllo delle condizioni. il modo in cui lo stai suggerendo non è soddisfare il formato. –

+0

@codesparkle: non molto spazio. if (condizione) {doThis();} else {doThat();} – tehdoommarine

risposta

18

Pensare agli operatori ternari come un metodo in questo caso. Dire a ? b : c è (per gli effetti che si sta valutando, vedi il commento di lasseespeholt) equivalente a chiamare il metodo pseudocodice:

ternary(a, b, c) 
    if a 
     return b 
    else 
     return c 

che è il motivo per cui le persone possono dire le cose come x = a ? b : c; è praticamente come dire x = ternary(a, b, c). Quando si dice (condition) ? doThis() : doThat(), siete in effetti dicendo:

if condition 
    return doThis() 
else 
    return doThat() 

Guardate cosa succede se proviamo a sostituire i metodi per quello che ritornano

if condition 
    return ??? 
else 
    return ??? 

Non ha nemmeno senso di considerarlo . doThis() e doThat() non restituiscono nulla, perché void non è un tipo di tipo istanziabile, quindi il metodo ternary non può restituire nulla, quindi Java non sa cosa fare con la propria affermazione e si lamenta.

Ci sono dei modi per aggirare questo, ma sono tutte cattive pratiche (puoi modificare i tuoi metodi per avere un valore di ritorno ma non fare nulla con ciò che restituiscono, potresti creare nuovi metodi che chiamano i tuoi metodi e poi return null, ecc.). Stai molto meglio usando solo una dichiarazione if in questo caso.

EDIT Inoltre, c'è un problema ancora più grande. Anche se restituivi valori, Java non considera a ? b : c una dichiarazione in alcun senso.

+1

" Dire a? b: c equivale a chiamare il metodo pseudocode "<- Nope. Considera la situazione in cui 'b' o' c' ha effetti collaterali. Quindi devi considerare quelli come lambda come fai nei tuoi esempi successivi. –

+0

Vero. Chiarirò che sto semplificando. – Jodaka

+3

@Jodaka, considero la tua modifica come la risposta corretta perché non si tratta veramente di restituire un valore, si tratta di Java non considera un valore? b: c come una dichiarazione. – Kareem

2

L'operatore ternario è semplicemente zucchero sintattico.
Rende il codice più facile da leggere/scrivere, ma non aggiunge funzionalità reali.
Il suo uso principale era quello di comprimere diverse linee di codice in una singola riga, ed era molto utile quando si costruiscono stringhe che differiscono solo leggermente, in base ad alcune condizioni.

es.

Collection<?> col = ... 
System.out.println("There " + (col.size()==1 ? "is" : "are") + " " 
    + col.size() + " " + (col.size()==1 ? "element" : "elements") 
    + " in the collection"); 

invece di

Collection<?> col = ... 
String message = "There "; 
if(col.size()==1) 
    message += "is"; 
else 
    message += "are"; 
message += " "+col.size() 
if(col.size()==1) 
    message += " element"; 
else 
    message += " elements"; 
message += " in the collection"; 
System.out.println(message); 

Come si può vedere, si semplifica il codice.
(Nota: Nel secondo esempio è meglio utilizzare StringBuilder invece di concatenazione di stringhe)

Ma poiché (condition) ? doThis() : doThat(); (senza valori di ritorno) ha lo stesso significato di if(condition) doThis(); else doThat(); ci sarebbero due modi di scrivere la stessa cosa, senza aggiungendo funzionalità.Sarebbe complicare le cose:

  • per i programmatori: il codice non è uniforme
  • per l'attuazione del l'operatore ternario: ora deve anche supporto void metodi

Così No, l'operazione ternaria non può essere utilizzata per le chiamate al metodo condizionale. Utilizzare if-else invece:

if(condition) 
    doThis(); 
else 
    doThat(); 
1

L'operatore ternario (condizionale) restituisce un valore. Se i metodi non lo fanno, non possono essere utilizzati come parti dell'operatore (dove prende il valore).

Per capirlo meglio, pensiamo a un semplice operatore binario: +. Funziona in questo modo:

<eval1> + <eval2> --> <value> 

Ha bisogno di 2 parti valutabili e ne restituisce un altro. Se hai digitato

doThis() + doThat(); 

o anche

gimmeAValue = doThis() + doThat(); 

fallirebbe, in quanto né doThis()doThat() valutare a qualsiasi cosa (loro "ritorno" void). Naturalmente, sia <eval1> sia <eval2> devono essere di tipo "compatibile" per consentire all'operatore + di gestirli e restituire un valore di qualche tipo.

Ora vediamo l'operatore ternario:

<evalBoolean> ? <eval1> : <eval2> --> <value> 

ci vogliono 3 valutabili parti, e restituisce un valore.

La prima parte valutabile deve essere comprensibile (calcolabile) dal compilatore come booleano. Sarà usato per decidere quale delle altre 2 parti valutabili deve essere restituita.

Le altre due parti valutabili devono essere, beh ... valutabili. A qualcosa. Di certo tipo.

In altre parole: l'operatore condizionale ternario è inteso per restituire qualcosa, non come ramificazione del codice. Usato in questo modo:

gimmeAValue = testMe() ? returnThis() : returnThat();