【问题标题】:Guava's EventBus - visibility of @SubscribeGuava 的 EventBus - @Subscribe 的可见性
【发布时间】:2018-04-10 09:44:00
【问题描述】:

接口方法的注解不会继承到实现该接口的对象,afaik。 SO search results.

我想和 Guava 的 EventBus 一起使用一个接口,它要求一个对象有一个带有 @Subscribe 注释的回调方法。 我想知道是否可以简单地将该注释放入接口中并让对象实现该侦听器接口。根据above,这应该不工作。但是,它确实有效(参见下面的代码)。

为什么?

我的机器是 Java 1.8.0_151(32 位)和 Windows 7。

import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

/**
 * This test should fail, but... it works!
 */
public class EventTests {


    @Test
    public void test_events_are_heard() {

        MyListener listener = new MyListener();
        DeafListener deafListener = new DeafListener();
        EventBus bus = new EventBus();
        bus.register(listener);
        bus.register(deafListener);
        bus.post(new MyEvent());
        assertEquals(1, listener.eventCount);     // ok
        assertEquals(0, deafListener.eventCount);   // ok
    }

    // this interface includes the @Subscribe annotation
    private interface Listener {
        @Subscribe
        public void onEvent(MyEvent event);
    }

    // this interface does not include the @Subscribe annotation
    private interface NoListener {
        public void onEvent(MyEvent event);
    }

    // just something different from Object
    private static class MyEvent {
    }       

    // implementation of "Listener" (with @Subscribe in interface)
    private static class MyListener implements Listener {
        int eventCount = 0;
        @Override
        public void onEvent(MyEvent event) {
            eventCount ++;
        }
    }

    // IDENTICAL implementation as above, but of "NoListener" 
    // (without @Subscribe in interface)
    private static class DeafListener implements NoListener {
        int eventCount = 0;
        @Override
        public void onEvent(MyEvent event) {
            eventCount ++;
        }
    }

}

【问题讨论】:

    标签: java guava event-bus greenrobot-eventbus


    【解决方案1】:

    你是对的……也是错的。

    你是对的,@Subscribe 注释没有被继承。您可以通过MyListener.class.getMethod("onEvent", MyEvent.class).getAnnotation(Subscribe.class) != null这样的测试来检查它。

    但是,感觉如果在接口中定义了订阅方法来注册它是正确的。

    所以 this was discussed at length within the Guava team 过去和最小意外原则规定,如果任何声明方法被注释,那么它们注册的实现就会被订阅。

    我不得不承认,我检查了the documentation 和the Javadoc 并没有看到任何关于您的问题的具体内容,尽管感觉有必要提及。想起多年前的讨论,不得不在封闭的问题中找到答案。

    【讨论】:

    • 哇,我真的希望这被记录在案,所以我知道以这种方式使用它是“正确的”(尽管整个总线设计为在没有接口的情况下工作,但我在某处阅读了该讨论)。将其记录在案也可能意味着当此行为发生变化时需要更改说明,对吗?非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多