Estoy estudiando cambiar expresiones y creo que encontré un comportamiento extraño:
public static boolean isTimeToParty(Day day) { switch (day) { case MONDAY -> dog(); //expression allowed case TUESDAY -> 2 + 2; //error: not a statement case WEDNESDAY -> true; //error: not a statement default -> System.out.println(""); } return false; } public static int dog() { return 2; } ¿Por qué puedo escribir como valor dog() que es una expresión pero no se permiten otros tipos de expresión? Intellij me indica el error "not a statement" .
Gracias por adelantado.
Una expresión de invocación de método también se puede utilizar como declaración, según la especificación del lenguaje:
14.8. Declaraciones de expresión
Ciertos tipos de expresiones se pueden usar como declaraciones siguiéndolas con punto y coma.
Declaración de expresión:
DeclaraciónExpresión ;
DeclaraciónExpresión:
Asignación
PreIncrementExpressionPreIncrementExpression
PreDecrementExpressionPreDecrementExpression
PostIncrementExpressionPostIncrementExpression
PostDecrementExpressionPostDecrementExpression
MétodoInvocación
ClassInstanceCreationExpression
La penúltima línea indica que se puede usar una expresión de invocación de método como declaración, por lo que se acepta dog() . El valor devuelto simplemente se descarta. 2 + 2 no se puede usar como una declaración.
IntelliJ reconoce que está intentando usar una declaración de cambio en lugar de una expresión de cambio. Si cambia su código para que sea:
int val = switch (day) { case MONDAY -> dog(); case TUESDAY -> 2 + 2; case WEDNESDAY -> true; default -> System.out.println(""); } Encontrará que el error ahora está en la declaración de impresión y el valor true porque no se pueden convertir a int . Esto se debe a que Intellij ahora reconoce su código como una expresión de cambio.
En otras palabras, todas las ramas de una expresión de cambio deben ser expresiones del mismo tipo y las ramas de una declaración de cambio deben ser declaraciones. El método call dog() es ambos, por lo que funcionará en cualquier contexto.
La cuestión es que 2 + 2 y true no son declaraciones de Java. En la documentación de referencia podemos leer lo siguiente:
Las declaraciones son aproximadamente equivalentes a oraciones en lenguajes naturales. Una declaración forma una unidad completa de ejecución. Los siguientes tipos de expresiones se pueden convertir en una declaración terminando la expresión con un punto y coma (;).
- Expresiones de asignación
- Cualquier uso de ++ o --
- Invocaciones de métodos
- Expresiones de creación de objetos
Este tipo de sentencias se denominan sentencias de expresión. Estos son algunos ejemplos de declaraciones de expresión:
// sentencia de asignación
aValor = 8933.234;// declaración de incremento
unValor++;// declaración de invocación del método
System.out.println("¡Hola mundo!");// declaración de creación de objeto
Bicicleta miBicicleta = new Bicicleta();
2 + 2 y true no son ninguno de esos, ya que son expresiones, de ahí el error de compilación en su declaración de cambio.