java - Guava 的 EventBus - @Subscribe 的可见性

标签 java guava event-bus greenrobot-eventbus

来自接口(interface)方法的注释不会继承到实现该接口(interface)的对象,afaik。 SO search results .

我想和 Guava 的 EventBus 一起使用一个接口(interface),这需要一个对象有一个用 @Subscribe 注解的回调方法。 我想知道我是否可以简单地将注释放入接口(interface)并让对象实现该监听器接口(interface)。根据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 ++;
        }
    }

}

最佳答案

你是对的……也是错的。

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

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

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

我不得不承认我检查了the documentationthe Javadoc并且没有看到任何关于您的问题的具体信息,即使感觉有必要提及。我记得多年前的讨论,不得不在封闭的问题中找到答案。

关于java - Guava 的 EventBus - @Subscribe 的可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49750402/

相关文章:

java - 基于参数真实类型的重载方法选择

java - Spring Boot Actuator - 无法禁用/信息端点

apache-spark - 从org.apache.hadoop.mapreduce.lib.input.FileInputFormat.getSplits到 Guava 的StopWatch的IllegalAccessError

java - Guava 如何过期其 CacheBuilder 中的条目?

java - Guava 重复键异常 IllegalArgumentException

java - Guava eventbus 有订阅者吗?

java - 将java流切换为密码流

java - 对话框 fragment 中未显示标题

java - 使用 Eventbus 重用事件对象

java - Vertx 中同步发送 EventBus 消息