Java 8 функциональный интерфейс неоднозначной ссылки (это ошибка?)

У меня есть две функции, подобные этим:

public static <In extends Number, Out extends Number> Out test(In in, Function<In, Out> f) {
    Out x = f.apply(in);
    return test(in, x);
}

public static <In extends Number, Out extends Number> Out test(In in, Out out) {
    return out;
}

Для меня очевидно, что они не могут (!) столкнуться и что вызовы не могут быть двусмысленными. Однако, с самой последней версией Java 8, следующий вызов завершается с ошибкой:

Test.test(2, Integer::new);

с Error:(17, 16) java: reference to test is ambiguous both method <In,Out>test(In,java.util.function.Function<In,Out>) in org.test and method <In,Out>test(In,Out) in org.test match

а

Test.test(2, new Function<Integer, Number>() {
    @Override
    public Number apply(Integer integer) {
       return 10;
    }
});

и

Test.test(2, (Function<Integer, Number>) integer -> 10);

работа.

Является ли это ошибкой в ​​компиляторе (или это не сработает?)

Подробнее о моей настройке ниже

Версия Java:

Desktop $ java -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

Ошибка:

Test.java:5: error: reference to test is ambiguous
    Test.test(2, Integer::new);
        ^
both method <In#1,Out#1>test(In#1,Function<In#1,Out#1>) in Test and method   <In#2,Out#2>test(In#2,Out#2) in Test match
where In#1,Out#1,In#2,Out#2 are type-variables:
In#1 extends Number declared in method <In#1,Out#1>test(In#1,Function<In#1,Out#1>)
Out#1 extends Number declared in method <In#1,Out#1>test(In#1,Function<In#1,Out#1>)
In#2 extends Number declared in method <In#2,Out#2>test(In#2,Out#2)
Out#2 extends Number declared in method <In#2,Out#2>test(In#2,Out#2)

Программа тестирования:

import java.util.function.Function;

public class Test {
  public static void main(String[] args) {
    Test.test(2, Integer::new);
  }

  public static <In extends Number, Out extends Number> Out test(In in, Function<In, Out> f) {
    Out x = f.apply(in);
    return test(in, x);
  }

  public static <In extends Number, Out extends Number> Out test(In in, Out out) {
    return out;
  }
}

Так как проблема подтверждена другими, я сообщил об этом как об ошибке для Oracle.

Ответы

Ответ 1

Test.test(2, Integer::new); не должен прерываться. Действительно, это не подводит меня. Продолжительность:

C:\Users\David>java -version
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
C:\Users\David>javac -version
javac 1.8.0_20

Из того, что я могу сказать, это самое последнее. На какой платформе вы работаете?

Как оказалось, это ошибка OSX (а не Windows). Если у кого-то есть поле * NIX, они также должны проверить код OP.

Ответ 2

У меня та же проблема, но я пробовал это:

Test.test(2, Function.identity() ); // OK
Test.test(2, val -> 2L ); // FAIL
Test.test(2, Function.<Integer>identity().andThen(a -> a * 2)); // OK
Test.<Integer,Long>test(2, val -> 2L ); // OK
Test.test(2, (final Integer a) -> a* 2 ); // FAIL

Пока это не удается в Javac (Debian Wheezy + jdk1.8.0_20x64), он отлично работает в Eclipse.

На стороне примечания, я предполагаю, что это одна из тех проблем вывода типа. Вероятно, вы должны заполнить отчет об ошибке.