我一直在 Java 中试验三元运算符 (
? :
),并注意到它会自动对其表达式执行类型转换。例如,此代码返回 2.0
而不是 2
:
System.out.println(false ? 1.0 : 2);
在常规
if-else
条件中,Java 显然不会以相同的方式执行类型转换,但对于三元运算符,它会执行类型转换。
为了确定结果类型,我使用了
getClass()
方法来区分 int
和 byte
等情况。对于 float
或 double
与 int
,差异很明显,因为像 2
这样的值会变成 2.0
。
这提出了几个问题:
为什么Java三元运算符首先要进行类型转换?
该运算符似乎遵循典型的 Java 类型提升层次结构(例如,
byte -> short -> int -> long -> float
)。然而,当涉及 int
时,如果 int
适合该类型的范围,它总是返回另一种类型。例如,在下面的代码中,结果是 byte
,其值为 1
:
System.out.println(true ? (int) 1 : (byte) 2);
这也适用于类似场景中的
short
。
我尚未使用三元运算符测试所有可能的类型组合,但有时类型转换行为似乎不一致或任意。
在这些情况下,Java 如何决定返回哪种类型?
在这些情况下,Java 如何决定返回哪种类型?
三元条件表达式的类型在 Java 语言规范第 15.25 节中指定。在这种特定情况下,它是一个数字条件表达式,因此相关小节是15.25.2。
您的观察
当涉及
时,如果int
适合该类型的范围,它总是返回另一种类型。int
基本正确。以下是规范的更准确说法
如果其中一个操作数为
类型,其中T
为T
、byte
或short
,而另一个操作数为char
int
类型的常量表达式 (§15.29),其value 可以用类型表示,则条件表达式的类型为T
。T
原始包装器的工作方式类似,但结果类型是原始类型,而不是包装器。
如果其中一个操作数是
类型,其中T
是T
、Byte
或Short
,而另一个操作数是Character
类型的常量表达式,其值可以用typeint
是对U
进行拆箱转换的结果,则条件表达式的类型为T
。U
所以
someBoolean ? (int)1 : (Byte)2
的类型是 byte
,而不是 Byte
。
另请注意
如果第二个和第三个操作数具有相同的类型,则这就是条件表达式的类型。
这与常规数字提升与算术运算符等的工作方式存在显着差异。
还有一些关于拳击和晋级
short
的规则。对于其他一切,均适用常规数字促销规则。