通过Java中的三元运算符传递方法参数

Anj*_* Jo 4 java ternary-operator return-value ocpjp

码:

public class Foo {

    static void test(String s){
        System.out.println("String called");
    }

    static void test(int s){
        System.out.println("int called");
    }

    public static void main(String[] args) throws Exception {

        test(5>8? 5:8);         // Line 1
        test(5>8? "he":"ha");   // Line 2

        test(5>8? 5:"ha");      // Line 3

        System.out.println(5<8? 5:"ha"); //Line 4
    }
}
Run Code Online (Sandbox Code Playgroud)

当我执行此代码时,出现以下错误 Line 3

Foo.java:24: error: no suitable method found for test(INT#1)
                test(5>8? 5:"ha");              // Line 3
                ^
Run Code Online (Sandbox Code Playgroud)

在三元运算符中使用类似的类型不会产生错误。但是使用不同的类型只会给方法调用带来错误,test(5>8? 5:"ha");但对调用有效System.out.println(5<8? 5:"ha");

当我添加另一个重载的方法时static void test(Object s){},然后进行//Line 3编译。

有人可以给我解释一下这种情况吗?

Daw*_*ica 6

Java中的每个表达式都有一个类型。在Java语言规范中,关于条件运算符的部分中包含一些复杂的规则,这些规则告诉我们如何查找条件表达式的类型,例如5 > 8 ? 5 : "ha"。但是简单来说,您总是得到第二个和第三个参数都是其成员的最特定的类型。

  • 因为5 > 8 ? 5 : 8,5和8都是int,所以整个表达式都具有type int。
  • 因为5 > 8 ? "he" : "ha","he"和"ha"都是String,所以整个表达式都具有type String。
  • 对于5 > 8 ? 5 : "ha",最适合同时适合5和"ha"是的类型Object。因此,整个表达式具有type Object。

现在,由于具有test了accept int和accept的版本String,因此表达式test ( 5 > 8 ? 5 : 8 )和表达式test ( 5 > 8 ? "he" : "ha" )都可以编译。

但是,如果您没有testaccepts 的版本Object,则test ( 5 > 8 ? 5 : "ha" )无法编译。

这是一个过分的简化。规则比我描述的要复杂得多,但这主要是因为它们考虑了涉及null操作数,自动装箱和自动拆箱的各种情况。