[英]How do you get event notifications back to the main program class of a Java console app?
I'm coming to Java from C#, and I'm really just trying to figure out how to do things in Java world. 我从C#入Java,实际上我只是想弄清楚如何在Java世界中做事。 I'm running Java 8 in IntelliJ IDEA.
我在IntelliJ IDEA中运行Java 8。 I found this explaining events in Java as basically being hand-made through manual registration and an interface method call.
我发现这说明Java中的事件基本上是通过手动注册和接口方法调用手动完成的。 The code example has enough problems that I assume it was never compiled.
该代码示例有足够的问题,我认为它从未被编译过。 After cleaning that up a bit I have this:
清理了一点之后,我有了这个:
Interface MetronomeEvent: 接口MetronomeEvent:
public interface MetronomeEvent {
void Tick(Date tickDate);
}
Class EventFiringSource: 类EventFiringSource:
public class EventFiringSource {
// Our collection of classes that are subscribed as listeners of our
protected List<MetronomeEvent> _listeners=new ArrayList();
// Method for listener classes to register themselves
public void addMetronomeEventListener(MetronomeEvent listener)
{
_listeners.add(listener);
}
// "fires" the event
protected void fireMetronomeEvent()
{
if (_listeners != null && !_listeners.isEmpty())
{
for (MetronomeEvent e:_listeners)
{
e.Tick(new Date());
}
}
}
public void Start()
{
fireMetronomeEvent();
}
}
Main console application: 主控制台应用程序:
public class MainApp implements MetronomeEvent {
public static void main(String[] args) {
EventFiringSource source = new EventFiringSource();
source.addMetronomeEventListener(this); // Adds itself as a listener for the event
source.Start();
}
public void Tick(Date tickDate)
{
System.out.println(tickDate.toString());
}
}
The one remaining error is source.addMetronomeEventListener(this);
剩下的一个错误是
source.addMetronomeEventListener(this);
where the compiler complains that it cannot reference MyApp.this
from a static context. 编译器抱怨它无法从静态上下文引用
MyApp.this
。 That makes sense, but I don't see any way then that I could, after implementing the MetronomeEvent interface on the main program class, actually pass it to source.addMetronomeEventListener()
for registration. 这是有道理的,但是我看不出有什么办法可以在主程序类上实现MetronomeEvent接口之后,将其实际传递给
source.addMetronomeEventListener()
进行注册。 Is it impossible to directly register the main program class for events? 是否可以直接为事件注册主程序类? Am I supposed to create and register a Listener class that implements MetronomeEvent and will act on behalf of the main application?
我是否应该创建并注册一个实现MetronomeEvent的侦听器类,该类将代表主应用程序运行? Like this?
像这样?
public class Listener implements MetronomeEvent {
public void Tick(Date tickDate){
System.out.println(tickDate.toString());
}
}
And then: 接着:
public static void main(String[] args) {
EventFiringSource source = new EventFiringSource();
Listener l=new Listener();
source.addMetronomeEventListener(l); // Adds another object to listen on behalf of main()
source.Start();
}
Based on Vince Emigh's comment/answer I was led to this Oracle doc on lamda expressions and to this one on method references . 根据文斯·埃米格(Vince Emigh)的评论/回答,我得到了有关lamda表达式的Oracle文档以及有关方法引用的 这一文档 。 I've found 3 ways to do this so far.
到目前为止,我已经找到3种方法来做到这一点。
1) Anonymous class: 1)匿名班:
source.addMetronomeEventListener(
new MetronomeEvent() {
@Override
public void Tick(Date tickDate) {
System.out.println("anonymous class:");
System.out.println(tickDate.toString());
}
}
); // Adds itself as a listener for the event
2) Lambda expression: 2)Lambda表达式:
source.addMetronomeEventListener(d -> System.out.println("lambda:\n"+d.toString()));
3) Method reference, which is the closest to what I am accustomed to. 3)方法参考,这是我最熟悉的方法参考。 A method is defined in the main class:
在主类中定义了一个方法:
public static void processTick(Date tickDate){
System.out.println("method reference:");
System.out.println(tickDate.toString());
}
...and then in the body of main() it is added as an event handler like this: ...然后在main()的主体中将其添加为事件处理程序,如下所示:
source.addMetronomeEventListener(MainApp::processTick);
This is not about events, it's about main()
and static methods in general. 这与事件无关,通常与
main()
和静态方法有关。
I would suggest writing your main() as 我建议将您的main()编写为
public static void main(String[] args) {
new MainApp(args).execute();
}
This way you're immediately jumping from static function world into object-oriented world. 这样,您立即从静态函数世界跳入了面向对象的世界。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.