为什么三元运算符会意外地转换整数?

问题描述 投票:0回答:2

我在某处看到过讨论,以下代码导致

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 casting ternary-operator conditional-operator
2个回答
43
投票

您需要阅读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。
  • 如果其中一个操作数是类型;字符,另一个操作数是 int 类型的常量表达式,其值可以用 char 类型表示,则条件表达式的类型为 char。
  • 否则,将对操作数类型应用二进制数值提升(第 5.6.2 节),并且条件表达式的类型是第二个和第三个操作数的提升类型。请注意,二进制数字提升执行拆箱转换(第 5.1.8 节)和值集转换(第 5.1.13 节)。

因此应用二进制数字提升,其开头为:

当运算符对一对操作数应用二进制数字提升时,每个操作数必须表示一个可转换为数字类型的值,以下规则按顺序适用,使用扩展转换(第 5.1.2 节)将操作数转换为必要:

  • 如果任何操作数是引用类型,则执行拆箱转换(第 5.1.8 节)。然后:
  • 如果其中一个操作数为 double 类型,则另一个将转换为 double。

这正是这里发生的情况 - 参数类型分别转换为

int
double
,第二个操作数(原始表达式中的第三个)的类型为
double
,因此总体结果类型为
double
.


3
投票

条件运算符中的数值转换? :

在条件运算符中,如果两个不同的数字类型,则以下转换规则在编译

时应用,以使它们的类型
相等,顺序为:

类型被转换为相应的
原始
类型,这称为
拆箱
如果一个操作数是 constant
 
a
(拆箱前不是 ?
),其值可以用另一种类型表示,则 
b
操作数将转换为另一种类型。 否则,较小的类型将转换为下一个较大的类型,直到两个操作数具有相同的类型。转换顺序为: :

->
    c
  • ->

    b -> c -> int

    ->
  • Integer
  • int ->

    byte
    ->
    short
    ->
    int
    ->

    long

  • 最终整个条件表达式获得其第二个和第三个操作数的类型。
    示例:
    如果将
    float
    double
    组合,则表达式变为
    char
    如果将 
    int
    long
    组合,则表达式变为
    float
    如果将 
    double
    char
     组合,则表达式变为 
    short

  • 如果将
int

Integer

组合,则表达式变为
Integer

在问题的示例中,200从
Integer
转换为
final int i = 5
,0.0从
Character
拆箱为
char
,整个条件表达式变成
short
,最终被装箱为
float
,因为
float
属于类型 
Integer

示例:

double


© www.soinside.com 2019 - 2024. All rights reserved.