Java 如何将实例方法引用定义为参数/参数
假设一个Java 如何将实例方法引用定义为参数/参数,java,lambda,arguments,parameter-passing,method-reference,Java,Lambda,Arguments,Parameter Passing,Method Reference,假设一个Person对象通过调用bookAppointment方法,请求一个Scheduler对象预订约会。但是现在没有预约。稍后,当一个约会打开时,一个约会将被预订–然后人对象想要得到通知。为了得到通知,我们需要一个特定的方法appointmentHasBeenBooked作为回调调用 为了简单起见,假设我们没有要传递的参数,并且在Person上没有为这个appointmenthasbooked方法返回值 public class Person { // Callback - To
Person
对象通过调用bookAppointment
方法,请求一个Scheduler
对象预订约会。但是现在没有预约。稍后,当一个约会打开时,一个约会将被预订–然后人
对象想要得到通知。为了得到通知,我们需要一个特定的方法appointmentHasBeenBooked
作为回调调用
为了简单起见,假设我们没有要传递的参数,并且在Person
上没有为这个appointmenthasbooked
方法返回值
public class Person {
// Callback - To be invoked after the `Scheduler` object succeeds in booking an appointment.
public void appointmentHasBeenBooked() {
…
}
}
在Person
类上方法fooBar
的代码中,我们建立了一个Scheduler
对象。理想情况下,我将能够为来自该方法的回调传递一个简单的方法引用。下面是我如何想象foorBar
方法,当它通过this::appointmenthasbooked
方法引用时
public class Person {
public void fooBar() {
Scheduler scheduler = … ;
scheduler.bookAppointment( this.id , this:: appointmentHasBeenBooked ) ; // Asking the scheduler to eventually book an appointment for this person, and when accomplished, notify this person by invoking the passed method.
…
}
// Callback - To be invoked after the `Scheduler` object succeeds in booking an appointment.
public void appointmentHasBeenBooked() {
…
}
}
这可能吗?我还没有定义一个接口,更不用说定义一个
➥ 如果这是可能的,我如何定义Scheduler
methodbookhasbeenappoint
上的参数/参数作为方法引用
接收方法引用的方法如何调用该方法
public class Scheduler {
public void bookAppointment( UUID id , methRef ) {
… book the appointment
invoke_methRef ;
}
}
在上面的代码中,我要说明什么:
methRef
invoke\u methRef
this::toString
。但是我没有看到任何关于定义传递的方法引用的接收端的解释
我知道实现我的目标的更为漫长的迂回的方法:用一个方法定义一个接口AppointBookingObserver
。将该接口嵌套在调度程序
类上。将Person
声明为实现调度程序。AppointmentBookingObserver
。然后将bookAppointment
上的第二个参数定义为AppointmentBookingObserver
对象。bookAppointment
方法最终将调用单一接口方法:observer.appointmenthasbooked
。这是可行的,但对于这样一个简单的单一回调场景来说似乎有些过头了。只需传递this::appointmentHasBeenBooked
就会更简单、更清晰
这里没有线程。因此需要执行器、Runnable
,或者关注线程安全
如果您希望了解我的实际用例场景的详细信息,而不是上面这个人为的Person Scheduler示例,请参阅我的另一个问题。您认为的方法引用可以只是一种类型 然后
Scheduler scheduler = new Scheduler();
Person person = new Person();
scheduler.bookAppointment( person.id , person::appointmentBooked);
在的评论中已经确认,不为无参数的
void
操作添加另一个功能接口的原因是Runnable
已经达到了目的
所以你可以用
public class Scheduler {
public void bookAppointment(UUID id, Runnable methRef) {
… book the appointment
methRef.run();
}
}
作为
public class Person {
public void fooBar() {
Scheduler scheduler = … ;
scheduler.bookAppointment(this.id, this::appointmentBooked) ; // Asking the scheduler to eventually book an appointment for this person, and when accomplished, notify this person by invoking the passed method.
…
}
// Callback - To be invoked after the `Scheduler` object succeeds in booking an appointment.
public void appointmentBooked() {
…
}
}
public class Person {
public void fooBar() {
Scheduler scheduler = … ;
scheduler.bookAppointment(this.id, this, Person::appointmentBooked) ; // Asking the scheduler to eventually book an appointment for this person, and when accomplished, notify this person by invoking the passed method.
…
}
// Callback - To be invoked after the `Scheduler` object succeeds in booking an appointment.
public void appointmentBooked() {
…
}
}
但还有一种选择
public class Scheduler {
public <T> void bookAppointment(UUID id, T instance, Consumer<T> methRef) {
… book the appointment
methRef.accept(instance);
}
}
这强调了问题的“实例方法引用”方面,尽管此构造不强制要求使用者
是这样一个方法引用,但使使用这样一个方法引用更容易
另外,
Person::appointmentBooked
是一个非捕获方法引用,它将被评估为使用者
实例,该实例将在后续调用中重用。我的问题中不涉及线程,因此不需要Runnable
@Basil。不涉及多线程。Runnable在这里只是一个函数接口。啊,我想我明白了,只需使用Runnable
作为一个方便的预定义函数接口,而不是编写我自己的嵌套接口。这么简单。我将不得不考虑这一点。谢谢@巴兹尔:是的,这是最简单和最符合你需要的。在这里查看我多次关注的其他选项。所有这些似乎都不适合调用没有返回值的无参数方法的简单情况。但是Runnable
就是这样。我唯一担心的是,如果有人阅读我的代码,看到一个可运行的
,就会认为线程即将到来。在该页面或其他地方是否有其他界面可以工作?我想我可以发明自己的代码,在我的代码库中使用。但这似乎是许多人的共同需要。
public class Person {
public void fooBar() {
Scheduler scheduler = … ;
scheduler.bookAppointment(this.id, this, Person::appointmentBooked) ; // Asking the scheduler to eventually book an appointment for this person, and when accomplished, notify this person by invoking the passed method.
…
}
// Callback - To be invoked after the `Scheduler` object succeeds in booking an appointment.
public void appointmentBooked() {
…
}
}