dan*_*iel 5 java lambda java-8 method-reference
我正在尝试创建一个工作队列类(FooQueue),它具有:
当do函数是静态的时,代码编译,但是当函数是非静态的时,代码编译,即使根据这个,实例函数成员的定义是正确的.
应该改变什么来使其编译/运行?
public class App {
public static void main( String[] args ) {
FooQueue q = new FooQueue();
q.add( FooQueue::dos, new FooItem() ); // this compiles
q.add( q::do1, new FooItem() ); // this does not:
// does not consider q::do1 'delegate'
// as taking 2 parameters,
// with q being the first one
FooQueue q2 = new FooQueue2();
q.add( FooQueue2::dos, new FooItem() ); // want this to give compiler error
q.add( FooQueue2::do1, new FooItem() ); // want this to give compiler error
}
}
public class FooQueue {
public static void dos( FooQueue q, FooItem item ) {
System.out.println( "FooQueue:sdo" );
}
public void do1( FooItem item ) {
System.out.println( "FooQueue:do1" );
}
public void add( java.util.function.BiConsumer<FooQueue,FooItem> func, FooItem wi ) {
System.out.println( "FooQueue:addWorkItem2" );
func.accept( this, wi );
}
}
public class FooItem {
}
public class FooQueue2 {
public static void dos( FooQueue2 q2, FooItem item ) {
System.out.println( "FooQueue2:sdo" );
}
public void do1( FooItem item ) {
System.out.println( "FooQueue2:do1" );
}
}
Run Code Online (Sandbox Code Playgroud)
它与静态/非静态方法无关,也与泛型无关,只与BiConsumer定义有关.
BiConsumer 需要两个参数,因此您需要需要两个参数且不返回任何参数的lambda.
要解决此问题,请使用实例方法引用:
FooQueue q = new FooQueue();
q.add(FooQueue::do1, new FooItem());
Run Code Online (Sandbox Code Playgroud)
不要将它与静态方法引用混淆.FooQueue::do1是lambda的合成糖:
(qInstance, item) -> qInstance.do1(item));
Run Code Online (Sandbox Code Playgroud)
这种方法允许您只接受来自的方法FooQueue.
请注意,它q:do1与BiConsumer转换为:不兼容:
(item) -> q.do1(item)
Run Code Online (Sandbox Code Playgroud)
阅读有关Instance方法参考的更多信息
不同类的完整示例
public class App {
public static void main(String[] args) {
FooQueue q = new FooQueue();
FooQueue2 q2 = new FooQueue2();
q.add(FooQueue::do1, new FooItem());
// Equals to:
q.add((qInstance, item) -> qInstance.do1(item), new FooItem());
// q.add(FooQueue2::do1, new FooItem()); // not compile
}
}
class FooQueue {
void do1(FooItem item) {
System.out.println("FooQueue:do1");
}
void add(BiConsumer<FooQueue, FooItem> func, FooItem wi) {
System.out.println("FooQueue:addWorkItem");
func.accept(this, wi);
}
}
// class that pretends to be FooQueue
class FooQueue2 {
void do1(FooItem item) {
System.out.println("FooQueue2:do1");
}
}
class FooItem {
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
168 次 |
| 最近记录: |