【问题标题】:Lambda with wildcard generic type具有通配符泛型类型的 Lambda
【发布时间】:2018-10-10 10:02:26
【问题描述】:
在 java 中我有以下 lambda:
Function<? extends Number, Boolean> f = i -> true;
接下来我想通过以下方式使用这个 lambda:
public <T extends Number> Boolean use(T n) {
return f.apply(n);
}
但是编译器给出了'不兼容的类型:T 不能被转换为 capture#1 of ?扩展 java.lang.Number'
那是什么原因以及如何使用我定义的函数?
【问题讨论】:
标签:
generics
lambda
java-8
【解决方案1】:
在您的<T extends Number> Boolean use(T n) 方法中应用Function<? extends Number, Boolean> f = i -> true; 的问题是,您可以为f 分配一个函数,该函数接受Number 的一个子类的参数(比如Double),而您的use方法将尝试将Number 的另一个子类的实例传递给它(比如Integer)。
您可以将Function 定义更改为
Function<Number, Boolean> f = i -> true;
它将接受扩展Number 作为参数的任何类型。
或者您可以在单个泛型类中同时定义Function 和方法,这将确保传递给use() 的参数必须与f 预期的参数相匹配:
class Generic<T extends Number> {
Function<T, Boolean> f = i -> true;
public Boolean use(T n) {
return f.apply(n);
}
}
【解决方案2】:
您希望它通过Function“消费”元素,定义应该是:
static Function<? super Number, Boolean> f = i -> true;
问题是这些定义是不相关的,您可以提供扩展 Number 的某种类型的 Function,而您的 use 方法可能使用扩展 Number 的某些其他类型。 p>
要么创建一个将这两者包装在一起的类(如 Eran 所示);或声明您的Function 将占用Number;或任何可以通过? super Number至少是Number的东西