方法使用Java 8三元条件和未装箱的原语过载歧义

时间:2015-05-08 18:39:32

标签: java java-8 overloading

以下是Java 7中的代码编译,但不是openjdk-1.8.0.45-31.b13.fc21。

static void f(Object o1, int i) {}
static void f(Object o1, Object o2) {}

static void test(boolean b) {
    String s = "string";
    double d = 1.0;
    // The supremum of types 'String' and 'double' is 'Object'
    Object o = b ? s : d;
    Double boxedDouble = d;
    int i = 1;
    f(o,                   i); // fine
    f(b ? s : boxedDouble, i); // fine
    f(b ? s : d,           i); // ERROR!  Ambiguous
}

编译器声称最后一个方法调用不明确。

如果我们将f的第二个参数的类型从int更改为Integer,则代码会在两个平台上进行编译。为什么发布的代码不是用Java 8编译的?

1 个答案:

答案 0 :(得分:0)

简而言之:

编译器不知道选择哪种方法,因为在选择最具体的方法时,JLS中没有定义原语和引用类型之间的排序。

当您使用Integer而不是int时,编译器会使用Integer选择方法,因为Integer是Object的子类型。

当您使用Double而不是double时,编译器会选择不涉及装箱或拆箱的方法。

在Java 8之前,规则是不同的,因此这段代码可以编译。