I agree that this code:
var y = switch (0) { case 0 -> '0'; case 1 -> 0.0F; case 2 -> 2L; case 3 -> true; default -> 4; }; System.out.println(y); System.out.println(((Object) y).getClass().getName());
returns this:
0 java.lang.Character
But if you remove boolean:
var y = switch (0) { case 0 -> '0'; case 1 -> 0.0F; case 2 -> 2L; default -> 4; }; System.out.println(y); System.out.println(((Object) y).getClass().getName());
returns this:
48.0 java.lang.Float
I suppose this result is unexpected.
The switch case in java executes one statement from multiple ones. Thus, it is like an if-else-if ladder statement. It works with a lot of data types. The switch statement is used to test the equality of a variable against several values specified in the test cases.
You can also think of the -> as a return statement which returns a value from the switch expression, and thus breaks the execution of the switch expression. The Java switch expression also works with Java String values.
A switch works with the byte , short , char , and int primitive data types.
Depending on the context switch s can also sometimes be replaced by arrays or hashmaps.
According to the switch expression's JEP, a switch expression is a poly expression:
A switch expression is a poly expression; if the target type is known, this type is pushed down into each arm. The type of a switch expression is its target type, if known; if not, a standalone type is computed by combining the types of each case arm.
Because you don't have a target type, the expression is not checked to match any given type, which is expected.
You can verify this by replacing var
with a type:
int y = switch (0) { case 0 -> '0'; case 1 -> 0.0F; case 2 -> 2L; case 3 -> true; default -> 4; };
In my shell, this fails with:
| Error: | incompatible types: bad type in switch expression | possible lossy conversion from float to int | case 1 -> 0.0F; | ^--^ | Error: | incompatible types: bad type in switch expression | possible lossy conversion from long to int | case 2 -> 2L; | ^^ | Error: | incompatible types: bad type in switch expression | boolean cannot be converted to int | case 3 -> true; | ^--^
But if you remove boolean:...
It should be enough to see how the standalone type is determined (rules here):
The type of a standalone switch expression is determined as follows:
If the result expressions all have the same type (which may be the null type), then that is the type of the switch expression.
Otherwise, if the type of each result expression is boolean or Boolean, an unboxing conversion (5.1.8) is applied to each result expression of type Boolean, and the switch expression has type boolean.
Otherwise, if the type of each result expression is convertible to a numeric type (5.1.8), the type of the switch expression is the result of numeric promotion (5.6) applied to the result expressions.
Otherwise, boxing conversion (5.1.7) is applied to each result expression that has a primitive type, after which the type of the switch expression is the result of applying capture conversion (5.1.10) to the least upper bound (4.10.4) of the types of the result expressions.
As far as I can see, when you remove the boolean expression, you're left with numeric expressions (char
'0'
(int 48
) is promoted to float
48.0
). See third bullet point above.
And as for why float
is the result's type, see the Numeric Contexts section.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With