正确的参数化通用java事件处理程序的方法

时间:2013-01-25 21:27:52

标签: java generics

我有一些代码如下(摘录):

public interface Event<S> {
    S getSource();
}

public interface Subscriber<E> {
    void update(E event);
}

public interface EventPublisher<S, E extends Event<S>> {
    void addSubscription(S source, Subscriber<E> subscriber);
    void removeSubscription(S source, Subscriber<E> subscriber);
}

public class SubscriptionManager<S, E extends Event<S>> implements Subscriber<E>, EventPublisher<S, E> {
    ...
}

public class MyEvent implements Event<MyEventSource> {
    ...
}

这一切都很好,但是,我的问题是当我尝试这样的事情时:

public class MyEventHandler {
    private final SubscriptionManager<Class<? extends Event<?>>, ? extends Event<?>> subscriptionManager = new SubscriptionManager<>();

    Subscriber<? extends Event<?>> subscriber = ...;
    subscriptionManager.addSubscription(MyEvent.class, subscriber); **// Compile error**
}

我收到以下错误:

The method addSubscription(Class<? extends Event<?>>, Subscriber<capture#3-of ? extends Event<?>>) in the type SubscriptionManager<Class<? extends Event<?>>,capture#3-of ? extends Event<?>> is not applicable for the arguments (Class<MyEvent>, Subscriber<capture#5-of ? extends Event<?>>)

谁能告诉我什么是错的?

由于

1 个答案:

答案 0 :(得分:3)

老实说,我认为您的代码中存在一些设计错误。它几乎看起来像一个完美设计的模式,但有些东西不会加起来。您可以省略一半通用参数并使其更直接。

请考虑以下代码。整个框架由单个参数进行参数化。一切都编译,没有使用原始类型。 另请注意,MyEvent从未在框架定义中使用。这是一个方便的课程。 您可以安全地调用subscriptionManager.update(new MyEvent());代码中的某个地方。

也可能有更复杂的安排,但我相信这是你需要的。 如果这对你有用,请告诉我。

static interface Event<S> {
    S getSource();
}

static interface Subscriber<S> {
    void update(Event<S> event);
}

static interface EventPublisher<S> {
    void addSubscription(Class<S> sourceClass, Subscriber<S> subscriber);
    void removeSubscription(Class<S> sourceClass, Subscriber<S> subscriber);
}

static class SubscriptionManager<S> implements Subscriber<S>, EventPublisher<S> {
    public void addSubscription(Class<S> sourceClass, Subscriber<S> subscriber) {
    }
    public void removeSubscription(Class<S> sourceClass, Subscriber<S> subscriber) {
    }
    public void update(Event<S> event) {
    }
}

static class MyEvent implements Event<String> {
    public String getSource() {
        return null;
    }
}

static class MyEventHandler {
    private final SubscriptionManager<String> subscriptionManager = new SubscriptionManager<String>();
    public MyEventHandler() {
        Subscriber<String> subscriber = null;
        subscriptionManager.addSubscription(String.class, subscriber);
    }
}