![](/img/trans.png)
[英]Why does char overloading not work with integers and chars inside ternary expressions?
[英]Why does the ternary operator unexpectedly cast integers?
我在某处看到它讨论以下代码导致obj
为Double
,但它从左侧打印200.0
。
Object obj = true ? new Integer(200) : new Double(0.0);
System.out.println(obj);
结果:200.0
但是,如果您将不同的对象放在右侧,例如BigDecimal
,则obj
的类型应该是Integer
。
Object obj = true ? new Integer(200) : new BigDecimal(0.0);
System.out.println(obj);
结果:200
我认为其原因与将左侧转换为double
的方式与integer
/ double
精度比较和计算中发生的情况相同,但这里的左侧和右侧不会以这种方式交互。
为什么会发生这种情况?
您需要阅读Java 语言规范的第 15.25 节。
特别是:
否则,如果第二个和第三个操作数具有可转换(第 5.1.8 节)为数字类型的类型,则有几种情况:
- 如果操作数之一是 byte 或 Byte 类型,另一个是 short 或 Short 类型,则条件表达式的类型为 short。
- 如果其中一个操作数是 T 类型,其中 T 是 byte、short 或 char,而另一个操作数是 int 类型的常量表达式,其值可在类型 T 中表示,则 > - 条件表达式的类型为 T。
- 如果其中一个操作数是 Byte 类型,另一个操作数是一个 int 类型的常量表达式,其值可以用 byte 类型表示,则条件表达式的类型是 byte。
- 如果其中一个操作数是 Short 类型,而另一个操作数是 int 类型的常量表达式,其值可在类型 short 中表示,则条件表达式的类型为 short。
- 如果操作数之一是类型; Character 和另一个操作数是一个 int 类型的常量表达式,其值可以用 char 类型表示,则条件表达式的类型为 char。
- 否则,将二进制数值提升(第 5.6.2 节)应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。 请注意,二进制数字提升执行拆箱转换(第 5.1.8 节)和值集转换(第 5.1.13 节)。
因此应用了二进制数字提升,其开头为:
当运算符将二进制数字提升应用于一对操作数时,每个操作数都必须表示一个可转换为数字类型的值,以下规则按顺序应用,根据需要使用加宽转换(第 5.1.2 节)来转换操作数:
- 如果任何操作数是引用类型,则执行拆箱转换(第 5.1.8 节)。 然后:
- 如果任一操作数的类型为 double,则另一个将转换为 double。
这正是这里发生的情况 - 参数类型分别转换为int
和double
,第二个操作数(原始表达式中的第三个)是double
类型,因此整体结果类型为double
。
在条件运算符a
?
b
:
c
,如果b
和c
都是不同的数字类型,则在编译时应用以下转换规则以使它们的类型相等,依次为:
这些类型被转换为它们对应的原始类型,这称为unboxing 。
如果一个操作数是一个常量int
(拆箱前不是Integer
),其值可以用另一种类型表示,则int
操作数将转换为另一种类型。
否则,较小的类型将转换为下一个较大的类型,直到两个操作数具有相同的类型。 转换顺序为:
byte
-> short
-> int
-> long
-> float
-> double
char
-> int
-> long
-> float
-> double
最终整个条件表达式得到它的第二个和第三个操作数的类型。
例子:
如果将char
与short
结合使用,则表达式将变为int
。
如果将Integer
与Integer
结合使用,则表达式将变为Integer
。
如果将final int i = 5
与Character
,则表达式变为char
。
如果将short
与float
结合使用,则表达式将变为float
。
在问题的示例中, 200 从Integer
转换为double
, 0.0 从Double
拆箱为double
,整个条件表达式变为double
,最终被装箱为Double
因为obj
是Object
类型。
例子:
public static void main(String[] args) {
int i = 10;
int i2 = 10;
long l = 100;
byte b = 10;
char c = 'A';
Long result;
// combine int with int result is int compiler error
// result = true ? i : i2; // combine int with int, the expression becomes int
//result = true ? b : c; // combine byte with char, the expression becomes int
//combine int with long result will be long
result = true ? l : i; // success - > combine long with int, the expression becomes long
result = true ? i : l; // success - > combine int with long, the expression becomes long
result = true ? b : l; // success - > combine byte with long, the expression becomes long
result = true ? c : l; // success - > char long with long, the expression becomes long
Integer intResult;
intResult = true ? b : c; // combine char with byte, the expression becomes int.
// intResult = true ? l : c; // fail combine long with char, the expression becomes long.
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.