繁体   English   中英

如何将事件通知返回到Java控制台应用程序的主程序类?

[英]How do you get event notifications back to the main program class of a Java console app?

我从C#入Java,实际上我只是想弄清楚如何在Java世界中做事。 我在IntelliJ IDEA中运行Java 8。 我发现说明Java中的事件基本上是通过手动注册和接口方法调用手动完成的。 该代码示例有足够的问题,我认为它从未被编译过。 清理了一点之后,我有了这个:

接口MetronomeEvent:

public interface MetronomeEvent {
    void Tick(Date tickDate);
}

类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();
    }
}

主控制台应用程序:

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());
    }
}

剩下的一个错误是source.addMetronomeEventListener(this); 编译器抱怨它无法从静态上下文引用MyApp.this 这是有道理的,但是我看不出有什么办法可以在主程序类上实现MetronomeEvent接口之后,将其实际传递给source.addMetronomeEventListener()进行注册。 是否可以直接为事件注册主程序类? 我是否应该创建并注册一个实现MetronomeEvent的侦听器类,该类将代表主应用程序运行? 像这样?

public class Listener implements MetronomeEvent {
    public void Tick(Date tickDate){
        System.out.println(tickDate.toString());
    }
}

接着:

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();
}

根据文斯·埃米格(Vince Emigh)的评论/回答,我得到了有关lamda表达式的Oracle文档以及有关方法引用的 这一文档 到目前为止,我已经找到3种方法来做到这一点。

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表达式:

source.addMetronomeEventListener(d -> System.out.println("lambda:\n"+d.toString()));

3)方法参考,这是我最熟悉的方法参考。 在主类中定义了一个方法:

public static void processTick(Date tickDate){
    System.out.println("method reference:");
    System.out.println(tickDate.toString());
}

...然后在main()的主体中将其添加为事件处理程序,如下所示:

source.addMetronomeEventListener(MainApp::processTick);

这与事件无关,通常与main()和静态方法有关。

我建议将您的main()编写为

public static void main(String[] args) {
    new MainApp(args).execute();
}

这样,您立即从静态函数世界跳入了面向对象的世界。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM