5

代码:

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
    }
}

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

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

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

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

谁能解释一下这种情况?

4

3 回答 3

7

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

  • For 5 > 8 ? 5 : 8, both 5and 8are int,所以整个表达式都有 type int
  • For 5 > 8 ? "he" : "ha", both "he"and "ha"are String,所以整个表达式都有 type String
  • 因为5 > 8 ? 5 : "ha",适合两者的最具体的5类型"ha"Object。所以整个表达式都有 type Object

现在,由于您拥有test该 acceptint和 acceptString的版本,因此表达式test ( 5 > 8 ? 5 : 8 )test ( 5 > 8 ? "he" : "ha" )两者都可以编译。

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

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

于 2016-11-10T06:36:58.607 回答
0

您在计算表达式之前调用该方法。由于该方法没有test(Object o)的重载,因此它不起作用。

解析左侧表达式后调用该方法。

5>8?test(5):test("ha")
于 2016-11-10T06:26:04.687 回答
0

当你调用函数时

test(5>8? 5:8);
方法(在当前情况下)旨在发送参数,因此括号内的整个内容被视为参数,并且在您评估 int 和 String 时没有适当/合适的方法来处理此类调用(其参数应该是 Object)在其中一个陈述中。因此,三元运算符不能在那里实现。

因此,您可以使用这样的代码

(5 > 8) ? test(param1): test(param2);


或创建另一个接受 Object 作为参数的测试方法,然后评估该测试方法中的内容。像这样

void test(Object o){
    //manipulate things here
}
于 2016-11-10T06:38:36.770 回答