我同意这段代码:
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());
返回:
0
java.lang.Character
但是如果删除布尔值:
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());
返回:
48.0
java.lang.Float
我想这个结果是出乎意料的。
根据switch表达式的JEP,switch表达式是poly表达式:
switch表达式是poly表达式;如果目标类型已知,则将此类型下推到每个臂中。 switch表达式的类型是其目标类型(如果已知);如果不是,则通过组合每个案例臂的类型来计算独立类型。
因为您没有目标类型,所以不检查表达式以匹配任何给定类型,这是预期的。
您可以通过将var
替换为类型来验证这一点:
int y = switch (0) {
case 0 -> '0';
case 1 -> 0.0F;
case 2 -> 2L;
case 3 -> true;
default -> 4;
};
在我的shell中,这失败了:
| 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;
| ^--^
但是如果删除布尔值:...
它应该足以看到如何确定独立类型(rules here):
独立开关表达式的类型确定如下:
- 如果结果表达式都具有相同的类型(可能是null类型),那么这就是switch表达式的类型。
- 否则,如果每个结果表达式的类型是布尔值或布尔值,则对每个类型为Boolean的结果表达式应用拆箱转换(5.1.8),并且switch表达式的类型为boolean。
- 否则,如果每个结果表达式的类型可转换为数字类型(5.1.8),则switch表达式的类型是应用于结果表达式的数字提升(5.6)的结果。
- 否则,装箱转换(5.1.7)将应用于具有基本类型的每个结果表达式,之后切换表达式的类型是将捕获转换(5.1.10)应用于最小上限的结果(4.10.4 )结果表达式的类型。
据我所知,当你删除布尔表达式时,你会留下数字表达式(char
'0'
(int 48
)被提升为float
48.0
)。见上面第三点。
至于为什么float
是结果的类型,请参阅Numeric Contexts部分。