Lambda与通配符泛型类型

4

在Java中,我有以下lambda表达式:

Function<? extends Number, Boolean> f = i -> true;

接下来我想以以下方式使用这个lambda:

public <T extends Number> Boolean use(T n) {
  return f.apply(n);
}

但编译器报错“不兼容的类型:T 无法转换为 ? extends java.lang.Number 的 capture#1”,那么出现这种错误的原因是什么,我该如何使用我定义的函数呢?


请阅读此链接(https://dev59.com/KHVC5IYBdhLWcg3wjyDu),其与编程有关。 - Hadi J
2个回答

3
在您的<T extends Number> Boolean use(T n)方法中应用Function<? extends Number, Boolean> f = i -> true;存在的问题是,您可能会将一个仅适用于Number子类(如Double)参数的函数分配给f,而您的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类型的类型。
要么创建一个将这两个类包装在一起的单个类(就像Eran所展示的那样);要么声明你的Function,它将接受Number或任何至少可以通过? super Number成为Number的东西。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接