我已经开始学习java了,而且我对以下条件表达式感到不满:
((1<2)?5:(3<4))
在我发现此示例的书中,它说它是语法错误,因为它无法将数值转换为布尔值。 相同页面后,有一个不同练习的测试,包括这一个。在eclipse中编写和编译后,它给出了输出5。 为什么?我已经阅读了有关此运算符的一些内容,并清楚地表明这两个表达式必须是布尔值或算术运算符,所以它是eclipse的一个问题吗?
答案 0 :(得分:13)
当他们谈到编译器错误的情况时,就像这样
int a= ((1<2)?5:(3<4));
但是当(3&lt; 4)返回布尔值时,它不能分配给整数变量
但是当您只是System.out.println(((1<2)?5:(3<4)));
时,它不必将值分配给任何变量,并使用方法System.out.println(Object)
如果你稍微更改一下表达式并执行: - System.out.println(((1>2)?5:(3<4)))
那么它会打印true
作为输出
答案 1 :(得分:11)
条件运算符有三个操作数 - 第一个是条件,第二个和第三个是分开的“分支”。评估哪个分支取决于条件是评估为真还是假。
在您的情况下,您有:
1 < 2
5
3 < 4
现在的问题是这里的两个分支是不同的类型,因此表达式没有有用的原始结果类型。它(令人惊讶的是,IMO)有效,整体表达类型为Object
- 基本上,两个分支都涉及拳击。所以这个:
Object o = 1 < 2 ? 5 : 3 < 4;
相当于:
Object o = 1 < 2 ? (Integer) 5 : (Boolean) (3 < 4);
在JLS 15.25中指定 - 您的情况显示在“表15.25-B。条件表达式类型(原始第3操作数,第II部分)”中,表示当第三个操作数的类型为{{1}时第二种类型为boolean
,结果为int
- 基本上为lub(Integer,Boolean)
。
现在没关系:
Object
这样:
int x = 1 < 2 ? 5 : 4; // Both branches are of type int
...但您当前的情况有一个类型为// Very confusing with all these conditions, but valid!
boolean y = 1 < 2 ? 5 < 6 : 3 < 4; // Both branches are of type boolean
的分支,另一个类型为int
。
答案 2 :(得分:2)
唯一的问题&#34;这个三元运算符就是它返回不同的类型。
让我们用伪代码中的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;
}
}
因此表达式在某些条件下可能有效。
例如,Object o = ((1<2)?5:(3<4));
编译正常(3 < 4
部分有警告),因为Object
可以从原始boolean
和{{1}中加框}。
答案 3 :(得分:2)
如果您将其传递给System.out.println()
,则不会抱怨,因为所有值都会转换为字符串。
所以,
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));
将导致编译错误。
答案 4 :(得分:2)
由于在a?b:c
表达式中,b
和c
的类型可能不同,因此Java编译器必须尝试推断表达式的返回类型,以查找类型这适合两个操作数。
这是通过查看类型树并找到最近的共同祖先来完成的。对于参考类型,在最坏的情况下,这个最接近的共同祖先是Object
。 (1 > 2) ? new StringBuilder() : new ArrayList();
将返回类型为Object
,因此,如果您要将其分配给Object
类型的变量(或将其传递给期望参数为Object
的方法()),没关系。否则,您将收到编译错误,因为无法保证结果可以转换为任何其他类型。
您的方案稍微复杂一点的地方在于它将基元定义为b
和c
:int
和boolean
。这些必须首先自动装箱到Integer
和Boolean
,然后上述过程正常运行,返回类型为Object
。但是,如果您要将Object
分配给int
,那将无法正常工作,因此int x = ((1<2)?5:(3<4));
无法编译,但Object x = ((1<2)?5:(3<4));
有效。< / p>
注意:在实践中,由于可能存在多个不相关的共同祖先,但这并没有改变基本原则。
答案 5 :(得分:0)
?
是一个三元运算符,详见JSL (§15.25):
variable = condition ? value if true : value if false;
示例
String isFalse = 3 < 4 ? "true" : "false"; // false
String isTrue = 3 == 3 ? "true" : "false"; // true
条件表达式的类型确定如下:
如果第二个和第三个操作数具有相同的类型(可能是null类型),那么这就是条件表达式的类型。
如果第二个和第三个操作数之一是原始类型T,而另一个操作数的类型是将装箱转换(第5.1.7节)应用于T的结果,那么条件表达式的类型是吨。
如果第二个和第三个操作数之一是null类型而另一个操作数的类型是引用类型,则条件表达式的类型是该引用类型。
否则,如果第二个和第三个操作数的类型可转换(第5.1.8节)为数字类型,则有几种情况:
现在,了解这一点并翻译你的表达:
((1<2)?5:(3<4))
您获得1<2=false
和3<4=false
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
答案 6 :(得分:0)
以下编译并正确运行,无论x
和y
的值是多少。你得到数字5或布尔值true。没有问题,因为结果未在任何地方分配(或者结果是Object
传递给println(Object o)
)。
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
答案 7 :(得分:0)
3&lt; 4将返回布尔值。不是int。
1&lt; 2?是的,然后打印5 但是,如果你要改变&#34;&lt;&#34;到&#34;&gt;&#34;你会得到&#34; true&#34;。