4

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

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<?>>)

谁能告诉我怎么了?

谢谢

4

1 回答 1

4

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

请考虑下面的代码。整个框架由单个参数参数化。一切都编译并且没有使用原始类型。另外,请注意 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);
    }
}
于 2013-01-26T11:09:15.153 回答