在我的情况下,我有一个消费者需要 ? extends String
的供应商并对其执行一些操作,因此声明如下所示:
final Consumer<? super Supplier<? extends String>> action = ...
问题是当我尝试执行该操作时,编译器似乎不高兴并抛出以下错误:
The target type of this expression must be a functional interface
就我而言,我有一个有名字的客户,因此以下行会触发此错误:
action.accept(customer::getName)
我的假设是? super Supplier<? extends String>
不再被视为函数接口(interface),因为它是捕获类型。
那么,有人可以给我一个关于这种情况的明确解释吗?
最佳答案
您为什么使用此 token ,? super 供应商
。这样做的目的是什么?您只需传递一个声明为 @FunctionalInterface
的 Supplier
。试试这个,
public class MyConsumer implements Consumer<Supplier<String>> {
@Override
public void accept(Supplier<String> t) {
System.out.println(t.get());
}
public static void main(String[] args) {
MyConsumer myConsumer = new MyConsumer();
myConsumer.accept(() -> "Test");
}
}
@FunctionalInterface
注释对于代码的编译时间检查非常有用。你不能有超过一种方法。例如,Runnable
、Callable
都是很好的候选者。
但是您可以像这样进一步压缩它:
Consumer<Supplier<String>> myConsumer = (Supplier<String> supplier) -> System.out.println(supplier.get());
myConsumer.accept(() -> "Test");
由于编译器可以推断类型,因此这将进一步简化为,
Consumer<Supplier<String>> myConsumer = supplier -> System.out.println(supplier.get());
myConsumer.accept(() -> "Test");
关于Java8,有界通配符类型不被视为函数式接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49939166/