三元运算符的两个右手表达式都必须是兼容类型吗?

Must both right-hand expressions of a ternary operator be of compatible types?

我的练习测试书包含关于三元运算符的问题:

// What is the output of the following application?
public class Transportation {
    public static String travel(int distance) {
        return(distance < 1000 ? "train" : 10);
    }
    public static void main(String[] args) {
        travel(500);
    }
}

它不编译。给出的解释如下:

Ternary operations require both right-hand expressions to be of compatible data types. In this example, the first right-hand expression of the outer ternary operation is of type String, while the second right-hand expression is of type int. Since these data types are incompatible, the code does not compile, and Option C is the correct answer.

真的是这个原因吗?在我看来,这个示例无法编译,因为 10 不是字符串,而字符串是方法必须 return。 我问是因为 System.out.println(distance < 1000 ? "train" : 10); 编译运行没有问题。

您的方法声明 return 类型是 String。任何 return 语句必须生成与声明的 return 类型兼容的表达式。

然而,在这种情况下,return 类型可以是 int,这解释了编译器拒绝它的原因。

这不是三元运算符特有的,它也可以用等效的 if/else 块重现:

if(distance < 1000)
   return "train"; //This part is valid
else
    return 10; //This line will be rejected by the compiler

同理,最后一行会编译失败。这仅仅是因为基本类型检查。

System.out.println(distance < 1000 ? "train" : 10); compiles and runs without a problem.

这是因为编译器检测到 Stringint 的共同类型,即 Object,并决定选择此签名:

java.io.PrintStream#println(Object x) // available in the target class

但是,这不适用于 return 类型的方法。

如果您将 return 类型更改为 Object,您的代码也会通过编译。但这当然不是你想要做的。

Ternary operations require both right-hand expressions to be of compatible data types

-> 这部分实际上是有效的。这是一种解释它的方法:每个 两个表达式必须单独兼容:

String value = distance > 1000 ?
                 "train" //this must be compatible with String
                 :
                 10 //this too must be compatible with String (it isn't)

对比:

Object value = distance > 1000 ?
                 "train" //this must be compatible with Object (it is)
                 :
                 10 //this too must be compatible with Object (it is)

换句话说,对 System.out.println(distance < 1000 ? "train" : 10) 的调用类似于上面的最后一个示例,其中预期类型与两个表达式兼容。

is that really the reason? It looks to me like this example doesn't compile because 10 is not a String and a String is what the method must return

你的推理和作者的回答都对
我认为你的问题的正确答案是它们的结合。

1) 三元运算符无效

因为

2) 在当前上下文中,您分配给它的类型:int 无法分配给 String

您可以通过编译器发出的错误消息进行检查。

这里,你要考虑的是:

return(distance < 1000 ? "train" : 10);

作为编译器评估的两件事:

1) distance < 1000 ? "train" : 10 // 产生结果

2) returns (the produced result); // return 根据方法 return 类型

应该分配给字符串的结果

实际上,编译错误:

Transportation.java:3: error: incompatible types: bad type in conditional expression return(distance < 1000 ? "train" : 10);
int cannot be converted to String

指的是两个错误:条件表达式错误及其原因:int与String不兼容的错误

所以只有return中int和String不兼容的编译错误只有在编译时三元有效时才会出现。

写一个有效的三元表达式,你会看到编译器只会发出关于 return 语句的错误信号:

public static String travel(int distance) {
    return(distance < 1000 ? 15 : 10);
}

error: incompatible types: int cannot be converted to String

你是对的,解释令人困惑,因为不同的兼容类型可用于右侧表达式。

可以根据第二个和第三个操作数的类型here.

找到条件表达式结果类型的table

可以使用数字类型进行某些类型转换,如 this question 中所述。