这个问题在这里已有答案:

我在我的应用程序中使用了这段代码(简化版):

Object result;
if (check)
    result = new Integer(1);
else
    result = new Double(1.0);
System.out.println(result);
return result;

然后我决定将if-else语句重构为三元条件表达式,因此我的代码更简洁:

Object result = check ? new Integer(1) : new Double(1.0);
System.out.println(result);
return result;

事实证明,如果检查结果为true则两个版本会打印出不同的结果:

1

要么:

1.0

三元条件不等于相应的if-else吗?

===============>>#1 票数:25 已采纳

if / else和条件(三元)表达式并不完全相同 条件表达式的结果必须具有类型。

您正在观察数字类型提升(或类型强制)的影响。

以下是语言规范的摘录(参见此处 ),从描述条件表达式返回值的部分开始:

否则,如果第二个和第三个操作数具有可转换的类型(第5.1.8节)到数字类型,则有几种情况:

最后这种情况是(我在这里省略了其他情况):

否则,二进制数字提升(第5.6.2节)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。

这是与二进制数字促销相关的附加规范:

应用扩展基元转换(第5.1.2节)来转换由以下规则指定的一个或两个操作数:

  • 如果任一操作数的类型为double,则另一个操作数转换为double。

这是第一种情况(以下案例省略)。 double总是。

因此,无论条件表达式中第2个和第3个操作数的顺序如何,表达式的返回类型都将提升为double

===============>>#2 票数:6

简而言之,三元运算符与其他涉及数字类型提升的运算符没有区别。

当您有类似System.out.println(1 + 1.0) ,您希望它打印2.0 ,因为输出中使用的操作数受数字类型促销的约束。

它与三元运算符完全相同: System.out.println(true ? 1 : 1.0)将在执行相同的数字类型提升后打印1.0 ,如果表达式为1 + 1.0则会执行此操作。

它的工作原理非常简单:运算符结果的类型应该在编译时知道,而实际结果是在运行时确定的。

===============>>#3 票数:4

简短的回答

第一个示例显式地键入为Object ,这会导致向上转换。

第二个示例隐式输入为Double ,这会导致数字扩展。


答案很长

在使用Object的示例中,没有值的转换,只是一个向上转换,并且打印了1。

Object result;
if (1 == 1)
    result = new Integer(1);
else
    result = new Double(1.0);

如果你改为使用Double声明,它将是一个扩展并打印1.0。

Double result;
if (1 == 1)
    result = new Integer(1);
else
    result = new Double(1.0);

由于存在明确的类型,因此这些非常简单。

然而,三元表达式没有明确的类型,并且规则是非平凡的。

条件表达式的类型确定如下:

  • 如果第二个和第三个操作数具有相同的类型(可以是null类型),那么这就是条件表达式的类型。

  • 如果第二个和第三个操作数之一是原始类型T,而另一个操作数的类型是对T应用装箱转换(第5.1.7节)的结果,那么条件表达式的类型是T.

  • 如果第二个和第三个操作数之一是null类型而另一个操作数的类型是引用类型,则条件表达式的类型是该引用类型。

  • 否则,如果第二个和第三个操作数具有可转换的类型(第5.1.8节)到数字类型 ,则有几种情况:

    • 如果其中一个操作数的类型为字节或字节,另一个操作数的类型为short或Short,则条件表达式的类型为short。

    • 如果其中一个操作数是T类型,其中T是byte,short或char,另一个操作数是int类型的常量表达式(第15.28节),其值可以在类型T中表示,那么条件表达式的类型是T.

    • 如果其中一个操作数是T类型,其中T是Byte,Short或Character,另一个操作数是int类型的常量表达式(第15.28节),其值可以在类型U中表示,这是应用拆箱的结果转换为T,则条件表达式的类型为U.

    • 否则,二进制数字提升(第5.6.2节)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。 请注意,二进制数字提升执行值集转换(第5.1.13节),并可执行拆箱转换(第5.1.8节)。

  • 否则,第二和第三操作数分别是S1和S2类型。 设T1是将拳击转换应用于S1所产生的类型,让T2为应用到S2的装箱转换所产生的类型。 条件表达式的类型是将捕获转换(第5.1.10节)应用于lub(T1,T2)(第15.12.2.7节)的结果。

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25

数字IntegerDouble的“推广类型”是Double

===============>>#4 票数:2

除了@ pb2q的答案

你可以验证它

public class test {
    public static void main(String[] args) {
    Object result;
    Boolean check = true;

        if (check)
            result = new Integer(1);
        else
            result = new Double(1.0);
        System.out.println(result);
        result = check ? new Integer(2) : new Double(1.0);
        System.out.println(result);
    }
}

由于数字促销,它将打印2.0而不是2

===============>>#5 票数:1

除了现有答案之外,您还可以通过特定的方式转换为所需类型来避免此问题:

Object result = args.length < 100 ? (Object)2 : (Object)1.0;

Casting to Object将整数作为Integer,将double作为Double。 “:”两侧的表达式都是Object类型,因此编译器不需要生成任何进一步的转换。

  ask by fkn translate from so

未解决问题?本站智能推荐:

2回复

java三元条件奇怪的空指针异常[重复]

这个问题在这里已有答案: 为什么返回null并分配给引用类型的三元条件表达式会导致NullPointerException? [重复] 2个答案 有人可以解释我为什么在第一种情况下检测到空指针,但另一方面没有? 也许他总是看第一种类型,但为什么他只在条件错误
3回复

使用Java三元运算符时的奇怪行为

当我写这样的java代码时: 应用程序按预期运行但是当我这样做时: 我在第二行得到一个NullPointerException。 调试指针从第二行跳转到java.lang.Thread类中的this方法: 这里发生了什么? 这两个代码路径都完全等价不是吗? 编
2回复

在Java中使用if与三元opertator时,“错误”返回类型

在下面的类中,两种方法的返回类型与三元运算符的思想不一致: 相当于 第一个返回Double,第二个返回Long: 我可以想象这与编译器缩小了getWithQuestionMark()的返回类型有关,但是这种语言明智吗? 这肯定不是我所期望的。 任何见解都是最受欢迎
1回复

三元条件导致Java中CPU使用率异常

我正在运行以下代码来比较3种等效的计算环绕坐标的方法的性能: 我使用method1,method2和method3(每个测试一个方法)运行了此代码3次。 奇怪的是method1产生了几个Java进程,并设法利用了我双核cpu的近100%,而method2和method3仅产生了1个
2回复

使用三元运算符的无效Java语法[重复]

这个问题已经在这里有了答案: Java:三元组,无收益。 (用于方法调用) 5个答案 我正在使用队列实现堆栈。 我的pop()函数最初看起来像: 这个没有编译。 这个定义有什么问题?
1回复

Java三元运算符:是否可以在ART上进行类似于条件移动(组装)的行为?

我想清除一些关于Java中三元运算符的疑问。 在Java中,它看起来像: x =(c?a:b) 。 从我的阅读和经验来看,if / else似乎将其执行为一个分支,这意味着仅对一个语句进行评估(a或b,但不会同时执行)。 我想知道这是否总是对的。 在C语言中,可能会将其编译为条件
4回复

我可以在字符串连接中使用条件三元运算符吗?

我有以下疑问:我可以通过某种方式将条件三元运算符用于字符串连接吗? 我正在尝试做这样的事情: 这意味着在第一个String主干中,我想连接由以下项求值的值: 但是Eclipse向我签名此错误: 为什么? 怎么了? 如何解决此问题?
5回复

java:三元运算符(?:)中的NullPointerException很奇怪

请考虑以下代码片段: 据我所知(以及我的IDE可以告诉我的),变量testMin和verwachtMin应该等效。 如您所料,我宁愿写最后2行而不是前7行。但是,当我向该方法传递3个空值时,我在verwachtMin变量的计算中得到了NPE。 有人知道这怎么可能吗? 即使条
2回复

Java如何确定三元条件运算符表达式的类型?

有谁能解释一下? 输出: 65 一种 一种 一种 从我站立的地方看起来确实很奇怪。 我本以为只有A才能打印出来。 而且:怎么来的,当我替补0为i输出的变化? 对于i所有值,输出似乎相同,而不仅仅是0 。
1回复

三元运算表现得很奇怪[重复]

这个问题在这里已有答案: Java三元运算符优先级? 不同的输出给出 3个答案 奇怪的空指针异常情况:三元条件运算符不使用字符串连接 6个答案 我很难理解三元运算在下面的代码中是如何工作的。 在第first Statement block(Lin