【问题标题】: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】:

在您的&lt;T extends Number&gt; Boolean use(T n) 方法中应用Function&lt;? extends Number, Boolean&gt; f = i -&gt; 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的东西

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      相关资源
      最近更新 更多