mer*_*nan 2 lambda java-8 functional-interface
import org.junit.Test;
import java.util.stream.IntStream;
public class GomanTest {
@Test
public void someTest() {
IntStream.of(2, 3, 1).collect(Container::new, Container::add, null);
}
}
class Container<T> {
void add(T t) {
System.out.println("this is container " + t);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
this is container 2
this is container 3
this is container 1
Run Code Online (Sandbox Code Playgroud)
这在1.8.0_45.jdk上成功运行.Container#add如何被翻译成ObjIntConsumer #accept?
该方法Container.add是一个实例方法,需要调用实例.由于表单上的方法引用ClassName::methodName未绑定到实例,Container::add因此具有函数签名(Container<T>,T).
由于您没有为Container目标类型指定类型参数,编译器将推断Container<Object>.因此Container::add有推测签名(Container<Object>,Object)在这里,这是适合accept的方法ObjIntConsumer<Container<Object>>,其中有签名(Container<Object>,int).
第二个参数可以接受类型的值int,因为,在将其装箱后Integer,它可以赋值给Object.
如果将结果分配给变量,从而提供目标类型Container<Object>或Container<Integer>类似,则同样有效
Container<Integer> collected
= IntStream.of(2, 3, 1).collect(Container::new, Container::add, null);
Run Code Online (Sandbox Code Playgroud)
任何可以使用的类型参数Integer,例如Serializable或者也可以使用Number.
您可以在"Java 8中的特定类型的任意对象是什么意思?"中阅读有关实例方法的无界引用的更多信息.
作为旁注,collect流的方法不应该接受null参数而Stream实现不会.传递null与原始流一起工作是当前实现中的一个小故障,并且通过的代码null很可能在下一个版本中中断.正如Tagir Valeev指出的那样,Java 9当前的开发状态已经发生了变化.