Java 条件表达式“?”&引用;编译,尽管分支返回不同的类型

Java 条件表达式“?”&引用;编译,尽管分支返回不同的类型,java,ternary-operator,Java,Ternary Operator,我已经开始学习java,并且正在学习以下条件表达式: ((1<2)?5:(3<4)) ((1<2)?5:(3<4)) ((1当他们谈到编译器错误案例时,可能是这样的 int a= ((1<2)?5:(3<4)); int a=((1条件运算符有三个操作数-第一个是条件,第二个和第三个是单独的“分支”。计算哪个分支取决于条件的计算结果是真还是假 就您而言,您有: 条件:1

我已经开始学习java,并且正在学习以下条件表达式:

 ((1<2)?5:(3<4))
((1<2)?5:(3<4))

((1当他们谈到编译器错误案例时,可能是这样的

int a= ((1<2)?5:(3<4));

int a=((1条件运算符有三个操作数-第一个是条件,第二个和第三个是单独的“分支”。计算哪个分支取决于条件的计算结果是真还是假

就您而言,您有:

  • 条件:
    1<2
  • 分支1:
    5
  • 分支2:
    3<4
现在的问题是,这两个分支的类型不同,因此表达式没有有用的原始结果类型。它(令人惊讶的是,IMO)是有效的,总体表达式类型为
Object
-基本上,这两个分支都涉及装箱。因此:

Object o = 1 < 2 ? 5 : 3 < 4;
这也会:

// Very confusing with all these conditions, but valid!
boolean y = 1 < 2 ? 5 < 6 : 3 < 4; // Both branches are of type boolean
//所有这些条件都非常混乱,但都是有效的!
布尔y=1<2?5<6:3<4;//两个分支都是布尔类型

…但您当前的情况有一个分支类型为
int
,一个分支类型为
boolean
是一个三元运算符,详见:

范例

String isFalse = 3 < 4 ? "true" : "false";  // false
String isTrue  = 3 == 3 ? "true" : "false";  // true
所以如果你试图分配一个变量

boolean var = false ? 5 : false
int     var = false ? 5 : false
您将出现语法错误,因为它无法将数值转换为布尔值:

类型不匹配:无法从Object&compariable&Serializable转换为int
↑ (3这个三元运算符唯一的“问题”是它返回不同的类型

让我们使用伪代码中的
if
条件将其展开:

((1<2)?5:(3<4))

if (1 < 2) {
    // returns int
    return 5;
}
else {
    // either returns boolean (true)
    if (3 < 4) {
        return true;
    }
    else {
        return false;
    }
}

((1无论
x
y
的值是什么,下面的编译和运行都是正确的。您可以得到数字5或布尔值true。没有问题,因为结果没有分配到任何地方(或者说结果是传递给
println(对象o)
)的
对象)

intx=1;
int y=2;

System.out.println(x如果将其传递给
System.out.println()
它将不会抱怨,因为所有值都转换为字符串

所以


System.out.println((1因为在
a?b:c
表达式中,
b
c
的类型可能不同,Java编译器必须尝试推断表达式的返回类型,以找到适合两个操作数的类型

这是通过查看类型树并查找最近的公共祖先来完成的。对于引用类型,在最坏的情况下,此最近的公共祖先是
对象。
(1>2)?new StringBuilder():new ArrayList();
将有一个返回类型
Object
,因此,如果要将其分配给
Object
类型的变量(或将其传递给需要
Object
类型的参数的方法),则可以。否则将出现编译错误,因为无法保证结果可以转换为任何其他类型


您的场景稍微复杂一点的地方是,它的基本体是
b
c
:一个
int
boolean
。首先必须将它们自动装箱为
Integer
boolean
,然后上述过程正常运行,返回类型是
Object
。但是如果您需要t将
对象
分配给
int
,这将不起作用,因此为什么
int x=((1语句本身不会给出任何编译错误,但条件语句的结果不能分配给变量,因为如果条件为真(如当前情况)结果将是5,这是一个整数,但如果条件为false,则结果将为true,这是一个布尔值

因此,要获得编译错误,请执行以下操作:

Integer a = ((1>2)?5:(3<4));

整数a=((1>2)?5:(32)?5:(32)?5:(32)?5:(331@LaurentiuL.
3您能看到完整的代码行吗?这取决于左侧运算符是否可编译。@当然,如果在右侧上下文中使用,也可以。@Thomas,如果您将其分配给合适的类(对象),它将起作用。
Object i=((1实际上,
对象o=(1@Thomas是的,它肯定会起作用,但QO想了解他/她在书中读到了什么,以及为什么会有矛盾,所以我只是试图解释这一点没问题,我只是想指出为什么它仍然有效,即自动装箱也起到了作用。引用JLS很好,但你也应该引用下的相关部分“条件表达式的类型确定如下:…”。我从来没有说过这个@EJP,如果你看我引用了OP短语,并指出是类型不匹配。。。
false ? 5 : false
boolean var = false ? 5 : false
int     var = false ? 5 : false
Type mismatch: cannot convert from Object&Comparable<?>&Serializable to int<br>
                                   ↑ (3<4)                              ↑ variable assigned
((1<2)?5:(3<4))

if (1 < 2) {
    // returns int
    return 5;
}
else {
    // either returns boolean (true)
    if (3 < 4) {
        return true;
    }
    else {
        return false;
    }
}
    int x = 1;
    int y = 2;
    System.out.println(x<y ? 5 : 3<4);
    int x = 1;
    int y = 2;
    int a = x<y ? 5 : 3<4;  // Won't compile without a cast to int, if x > y, results in a `ClassCastException`.
Object o = x < y ? "String object" : new ArrayList();  // Works since the return type is compatible
System.out.println((1<2) ? 5 : (3<4));
//Will print 5

System.out.println((3<2) ? 5 : (3<4));
//Will print true
int i = ((3<2) ? 5 : (3<4));
boolean b = ((3<2) ? 5 : (3<4));
Integer a = ((1>2)?5:(3<4));
Boolean a = ((1>2)?5:(3<4));
Serializable a = ((1>2)?5:(3<4));
Object a = ((1>2)?5:(3<4));