dan*_*niu 7 java functional-programming java-8
使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
所以基本上编译器说"我知道你回来boolean
但你不应该,如果你不这样做我不知道使用什么方法"而不是"哦你回来了boolean
,你必须指的Predicate
是方法的版本" ?这种混乱是如何产生的?
我明白是否Predicate<T> extends Function<T, Boolean>
(所以他们有一个共同的类型)但事实并非如此.
我知道如何解决它; 如果我这样做就好了
callee(data, (Predicate<SomeDataClass>) d -> d.getRandom() > 0.5);
Run Code Online (Sandbox Code Playgroud)
但我很好奇是什么导致了它.
为了清楚起见,可以稍微简化一下:
public static void m(Predicate<Integer> predicate){
}
public static void m(Function<Integer, String> function){
}
Run Code Online (Sandbox Code Playgroud)
并用以下方式调用它:
m(i -> "test")
Run Code Online (Sandbox Code Playgroud)
你认为会发生什么?和你问题中的一样。
这里的编译器必须知道该方法才能找到目标类型,但它需要知道目标类型才能解析该方法(这就像死锁)。
当您添加强制转换时Predicate...
,您正在创建一个显式目标类型,据我所知,方法重载会考虑其返回类型。