Функция и параметр предиката неоднозначны? - PullRequest
0 голосов
/ 04 мая 2018

Используя Java 8, я получаю ошибку компилятора для следующего кода:

public class Ambiguous {
    public static void call() {
        SomeDataClass data = new SomeDataClass();
        callee(data, SomeDataClass::getString);
        // compiler errors:
        // 1. at callee method name:
        // The method callee(SomeDataClass, Function<SomeDataClass,String>) is ambiguous for the type Ambiguous
        // 2. at lambda:
        // Type mismatch: cannot convert from boolean to String
        callee(data, d -> d.getRandom() > 0.5);
    }

    public static void callee(SomeDataClass data, Function<SomeDataClass, String> extractString) {
        System.out.println(extractString.apply(data));
    }

    public static void callee(SomeDataClass data, Predicate<SomeDataClass> check) {
        System.out.println(check.test(data));
    }
}

// token data class
final class SomeDataClass {
    public String getString() {
        return "string";
    }

    public final double getRandom() {
        return Math.random();
    }
}

По сути, компилятор говорит: «Я знаю, что вы возвращаете boolean, но вы не должны этого делать, и если вы этого не сделаете, я не уверен, какой метод использовать» вместо «о, вы возвращаете boolean, Вы имеете в виду Predicate версию метода "? Как создается эта путаница?

Я бы понял, если бы Predicate<T> extends Function<T, Boolean> (поэтому у них был общий тип), но это не так.

Я знаю, как это исправить; хорошо, если я сделаю

callee(data, (Predicate<SomeDataClass>) d -> d.getRandom() > 0.5);

но мне любопытно, с чем это связано.

1 Ответ

0 голосов
/ 04 мая 2018

Это может быть немного упрощено для ясности:

public static void m(Predicate<Integer> predicate){

}

public static void m(Function<Integer, String> function){

}

И вызывая его с помощью:

m(i -> "test")

Как вы думаете, что произойдет? То же самое, что и в вашем вопросе.

Компилятор должен знать метод, чтобы найти целевой тип, но он должен знать целевой тип, чтобы разрешить метод (это похоже на тупик).

Когда вы добавляете приведение к Predicate..., вы создаете явный целевой тип , тип возвращаемого значения которого принимается во внимание при перегрузке метода, насколько я понимаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...