java - 函数和谓词参数不明确?

标签 java java-8 functional-programming

使用 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);

但我很好奇是什么原因造成的。

最佳答案

为了清楚起见,可以稍微简化一下:

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

}

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

}

并调用它:

m(i -> "test")

你认为会发生什么?与您的问题相同。

这里的编译器必须知道方法才能找到目标类型,但它需要知道目标类型才能解析方法(这就像一个死锁)。

当您向 Predicate... 添加强制转换时,您正在创建一个显式目标类型,方法重载时会考虑其返回类型我明白。

关于java - 函数和谓词参数不明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50169639/

相关文章:

java - Quartz Cron 触发器每 2 天运行一次

java - 尺寸有限的 Collection

java - 我想在特定长度后拆分一个字符串而不切割任何单词,不等于字符串

haskell - 什么是 "Scrap Your Boilerplate"?

Python:如果某个属性为真,则允许调用某些方法

java - Java泛型可以用值而不是类型参数化吗?

java - 检索月份名称和月份编号

java - Android API 中的 HexDump 在哪里?

Java 8 流 API - 是否有标准方法将 Map 中的每个值处理为不同类型?

java - 将复杂的 while 循环重构为 Java 8 流