2012-09-23 14 views
25

En páginas como http://en.wikipedia.org/wiki/?:, el operador ternario/condicional ?: parece utilizarse para asignaciones condicionales. Intenté usarlo para llamadas de método, así:¿Se puede utilizar el operador ternario/condicional de Java (? :) para llamar a métodos en lugar de asignar valores?

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

Ambos métodos vuelven vacío. Java me dice que no es una declaración.

Entonces, supongo que no puedo hacer llamadas de método condicional ... ¿o no?

+14

No, no así. Solo usa un 'si' como una persona normal. –

+1

Creo que el operador ternario debe asignar valores a una instancia de un tipo, con una comprobación de condición. la forma en que lo sugiere no cumple con el formato. –

+0

@codesparkle - no hay mucho espacio. if (condición) {doThis();} else {doThat();} – tehdoommarine

Respuesta

18

Piense en los operadores ternarios como un método en este caso. a ? b : c diciendo es (para los efectos que está considerando, véase el comentario de lasseespeholt) equivalente a una llamada al método pseudocódigo:

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

razón por la cual la gente puede decir cosas como x = a ? b : c; es básicamente como decir x = ternary(a, b, c). Cuando usted dice (condition) ? doThis() : doThat(), que está en efecto diciendo:

if condition 
    return doThis() 
else 
    return doThat() 

mira lo que pasa si tratamos de sustituir los métodos por lo que regresan

if condition 
    return ??? 
else 
    return ??? 

ni siquiera tiene sentido considerar que . doThis() y doThat() no devuelven nada, porque void no es un tipo instanciable, por lo que el método ternary tampoco puede devolver nada, por lo que Java no sabe qué hacer con su instrucción y se queja.

Hay formas de evitar esto, pero todas son malas prácticas (puede modificar sus métodos para obtener un valor de retorno pero no hacer nada con lo que devuelve, puede crear nuevos métodos que llamen a sus métodos y luego return null, etc.). Es mucho mejor que simplemente usar una declaración if en este caso.

EDIT Además, hay un problema aún mayor. Incluso si devolviera valores, Java no considera a ? b : c una declaración en ningún sentido.

+1

" Decir a? b: c es equivalente a llamar al método de pseudocódigo "<- No. Considere la situación donde 'b' o' c' tiene efectos secundarios. Entonces debes considerarlos como lambdas como lo haces en tus ejemplos posteriores. –

+0

Es cierto. Aclararé que me estoy simplificando. – Jodaka

+3

@Jodaka, considero su edición como la respuesta correcta porque no se trata de devolver un valor, se trata de que Java no considera una? b: c como una declaración. – Kareem

2

El operador ternario es simplemente azúcar sintáctico.
Hace que el código sea más fácil de leer/escribir, pero no agrega funcionalidad real.
Su uso principal era comprimir varias líneas de código en una sola línea, y era muy útil cuando se construían cadenas que diferían solo ligeramente, según algunas condiciones.

por ejemplo.

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

en lugar de

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

Como se puede ver, se simplifica el código.
(Nota: En el segundo ejemplo, es mejor utilizar StringBuilder en lugar de la concatenación de cadenas)

Pero desde (condition) ? doThis() : doThat(); (sin valores de retorno) tiene el mismo significado que if(condition) doThis(); else doThat(); habría dos formas de escribir la misma cosa, y sin agregando funcionalidad.Sólo sería complicar las cosas:

  • para los programadores: código no es uniforme
  • para la ejecución del operador ternario: ahora tiene que también apoyo void métodos

Así No, la operación ternaria no se puede usar para llamadas de método condicional. Use if-else en su lugar:

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

El operador ternario (condicional) devuelve un valor. Si sus métodos no lo hacen, no pueden usarse como partes del operador (donde toma el valor).

Para entenderlo mejor, pensemos en un simple operador binario: +. Funciona de esta manera:

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

Necesita de 2 partes evaluables y devuelve otra. Si escribió

doThis() + doThat(); 

o incluso

gimmeAValue = doThis() + doThat(); 

que fracasaría, ya que ni doThis() ni doThat() evaluar a cualquier cosa (que "retorno" void). Por supuesto, tanto <eval1> como <eval2> deben ser de algún tipo "compatible" para que el operador + pueda manejarlos y devolver un valor de algún tipo.

Ahora vamos a ver el operador ternario:

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

Se tarda de 3 partes evaluables, y devuelve un valor.

La primera parte evaluable debe ser comprensible (moldeable) por el compilador como un booleano. Se usará para decidir cuál de las otras 2 partes evaluables debe devolverse.

Las otras dos partes evaluables deben ser, bueno ... evaluables. A algo. De algún tipo.

En otras palabras: el operador condicional ternario está destinado a devolver algo, no como código de bifurcación. Usado de esta manera:

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