Java 条件表达式“?”&引用;编译,尽管分支返回不同的类型
我已经开始学习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
((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));