为了账号安全,请及时绑定邮箱和手机立即绑定

你能解释一下为什么第一个展开的方法引用不能编译吗?

你能解释一下为什么第一个展开的方法引用不能编译吗?

ibeautiful 2022-07-06 18:41:53
在这个例子中,传递一个方法引用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;    }}
查看完整描述

3 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

Stream.of(T)期望 anObject并且您在第一条语句中将方法引用传递给它。但是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.


查看完整回答
反对 回复 2022-07-06
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

this::a是无上下文的,可能意味着不同的东西。您需要提供一些上下文来帮助编译器弄清楚您的实际意思this::a。


Stream.<Supplier<String>>of(this::a);

不过,这Stream<Supplier<String>>似乎不是你想要的。如果您需要 a Stream<String>,请使用Stream.generate: 不需要额外的类型信息,因为该方法采用 a Supplier<T>(这里没有歧义)。


Stream.generate(this::a);

附带说明一下,这两个语句都希望您将它们的结果保存到变量中。定义正确类型的变量通常有助于解决此类问题。


Stream<Supplier<String>> s1 = Stream.of(this::a);

Stream<String> s2 = Stream.generate(this::a);

感谢@J-Alex 和@Holger 的宝贵评论。


查看完整回答
反对 回复 2022-07-06
?
皈依舞

TA贡献1851条经验 获得超3个赞

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;

whereObject不是功能接口,不会编译。


提供一个功能接口,这个例子编译:


Runnable a = this::a;

Stream.of(a);

在第二个例子中,wrap提供了一个功能接口Supplier


查看完整回答
反对 回复 2022-07-06
  • 3 回答
  • 0 关注
  • 95 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信