在此示例中,将方法引用传递给Stream.of
不起作用,但是一旦被包装,它便起作用。我不太明白为什么会这样。方法引用不等同于功能接口吗?
public class A {
String a() {
return "";
}
void b() {
Stream.of(this::a); // won't compile
Stream.of(wrap(this::a)); // will compile
}
static <T> Supplier<T> wrap(Supplier<T> f) {
return f;
}
}
答案 0 :(得分:1)
Stream.of(T)
需要一个Object
,并且您在第一条语句中将方法引用传递给它。但是Object
参数不是功能接口,因此它不能接受方法引用或未明确键入的lambda。
使用lambda时,也会产生错误:Stream.of(()->this.a())
。
一个更简单的示例可以是Stream.of(()-> "foo")
,它将不会编译。
但是,如果您输入方法引用或lambda,它将起作用:
Stream.of((Supplier<String>) this::a)
或
Stream.of((Supplier<String>) () -> this.a())
在工作语句中,您将Stream.of(T)
的参数传递给Supplier<String>
。这是指功能接口,但其输入方式与前面的工作示例相同,因此它作为期望Object
的参数有效。
答案 1 :(得分:1)
Stream.of
具有以下签名:
public static<T> Stream<T> of(T t)
将编译以下示例,因为您为T
显式提供了类型信息。
Stream<Supplier<String>> a = Stream.of(this::a);
第一个示例Stream.of(this::a);
等效于:
Object a = this::a;
其中Object
不是功能接口,因此不会编译。
此示例通过功能界面进行编译:
Runnable a = this::a;
Stream.of(a);
在第二个示例中,wrap
提供了功能接口Supplier
答案 2 :(得分:1)
this::a
是无上下文的,可能意味着不同的含义。您需要提供一些上下文,以帮助编译器弄清楚this::a
的实际含义。
Stream.<Supplier<String>>of(this::a);
尽管如此,Stream<Supplier<String>>
似乎并不是您想要的。如果您需要Stream<String>
,请使用Stream.generate
:由于该方法采用了Supplier<T>
(此处没有歧义),因此不需要额外的类型信息。
Stream.generate(this::a);
另一方面,两条语句都希望您将结果保存到变量中。定义正确类型的变量通常有助于解决此类问题。
Stream<Supplier<String>> s1 = Stream.of(this::a);
Stream<String> s2 = Stream.generate(this::a);
感谢@ J-Alex和@Holger的宝贵评论。