首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么StringBuilder::append是BiConsumer<StringBuilder,String>?

为什么StringBuilder::append是BiConsumer<StringBuilder,String>?
EN

Stack Overflow用户
提问于 2016-05-05 04:03:22
回答 2查看 970关注 0票数 5

我发现了一个使用Stream API的有趣示例:

代码语言:javascript
复制
Stream<String> stream = Stream.of("w", "o", "l", "f");
BiConsumer<StringBuilder, String> append = StringBuilder::append;
StringBuilder collected = stream.collect(StringBuilder::new, append, StringBuilder::append);
System.out.println(collected); //it works correctly

Stream.collect有三个参数:

代码语言:javascript
复制
Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner

BiConsumer接受两个参数,并且不返回任何内容。为什么这一行可以编译和工作?

代码语言:javascript
复制
BiConsumer<StringBuilder, String> append = StringBuilder::append;

StringBuilder没有空方法append(java.lang.StringBuilder,java.lang.String)。

EN

回答 2

Stack Overflow用户

发布于 2016-05-05 04:08:23

JLS 15.13.3或多或少指定了接收者--方法被调用的对象--可以成为函数接口的第一个参数:

如果格式为ReferenceType ::TypeArguments标识符,则调用方法的主体同样具有编译时声明的方法调用表达式的效果,编译时声明是方法引用表达式的编译时声明。方法调用表达式的运行时评估如§15.12.4.3、§15.12.4.4和§15.12.4.5所述,其中:

调用模式派生自编译时声明,如§15.12.3所述。

如果编译时声明是一个实例方法,那么目标引用就是调用方法的第一个形参。否则,没有目标引用。

如果编译时声明是一个实例方法,那么方法调用表达式的参数(如果有的话)是调用方法的第二个和后续的形参。否则,方法调用表达式的参数就是调用方法的形参。

编译时声明实际上是一个实例方法,因此StringBuilder成为调用方法的第一个参数,String成为第二个参数。

换句话说,方法引用SomeClass::instanceMethod等价于lambda (SomeClass receiver, args...) -> receiver.instanceMethod(args...)

票数 3
EN

Stack Overflow用户

发布于 2016-05-05 04:09:37

BiConsumer的第一个类型参数是该方法所应用的类型,第二个是该方法的单个参数。典型的例子就是ArrayList::add

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37037015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档