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 に答える