0

私は次のコードを持っています:

public interface IDoWork<K extends AbstractKey,V extends AbstractClass> {
    V obtain(K key, V value);
}

public class AbstractKey {
    String id;
}

public class AbstractClass {
    String name;
}

public class ConcreteA extends AbstractClass {
    String attributeA;
}

public class DoWorkA implements IDoWork<KeyA, ConcreteA> {

    private static final DoWorkA INSTANCE = new DoWorkA();

    public static DoWorkA getInstance() {
        return INSTANCE;
    }

    @Override
    public ConcreteA obtain(KeyA k, ConcreteA v) {
        //do something in real life
        return null;
    }

}

public class Main {

    public static void main(String[] args){
        KeyA a = new KeyA();
        ConcreteA c = new ConcreteA();
        IDoWork<? extends AbstractKey, ? extends AbstractClass> instance =
                WorkFactory.getInstance().obtainInstance(a);
        instance.obtain(a, c);
    }
}

public class WorkFactory {

    private static final WorkFactory INSTANCE = new WorkFactory();

    public static WorkFactory getInstance() {
        return INSTANCE;
    }

    public IDoWork<? extends AbstractKey, ? extends AbstractClass> obtainInstance(AbstractKey key){
        if(key instanceof KeyA){
            return DoWorkA.getInstance();
        }
        throw new IllegalArgumentException("Case not handled");
    }

}

次のコードでは:

KeyA a = new KeyA();
ConcreteA c = new ConcreteA();
IDoWork<? extends AbstractKey, ? extends AbstractClass> instance = WorkFactory.getInstance().obtainInstance(a);
instance.obtain(a, c);

この行はコンパイルされません:

instance.obtain(a, c);

Javaジェネリックの性質による。次のエラーが発生します。

タイプIDoWorkのメソッドget(capture#3-of?extends AbstractKey、capture#4-of?extends AbstractClass)は、引数(KeyA、ConcreteA)には適用できません。

それを行う別の方法はありますか?のタイプパラメータを省略した場合

IDoWork<? extends AbstractKey, ? extends AbstractClass> instance =...

タイプパラメータをから削除するとIDoWork...動作しますが、警告が表示されます。それを修正する方法はありますか?インターフェイスから型パラメーターを削除できることはわかっていますが、それで問題は解決しますが、キャストを行う必要がないようにジェネリックスを用意すると便利です+各クラスが明確であるため、コードが明確になりますを使用します。Depencendyインジェクションは、私が使用しているコードベースでは利用できないため、問題外です。

4

1 に答える 1

0

私はうまくいくものを持っていますが、あまり最適ではありません:

このように WorkFactory を定義する場合:

public class WorkFactory {
    private static final WorkFactory INSTANCE = new WorkFactory();
    public static WorkFactory getInstance() {
        return INSTANCE;
    }

    @SuppressWarnings("unchecked")
    public <K extends AbstractKey, V extends AbstractClass> IDoWork<K, V> obtainInstance(K key, V val) {
        if (key instanceof KeyA) {
            return (IDoWork<K, V>) DoWorkA.getInstance();
        }
        throw new IllegalArgumentException("Case not handled");
    }

}

その後、あなたのメインメソッドはきれいに動作するはずです:

public static void main(String[] args){
        KeyA a = new KeyA();
        ConcreteA c = new ConcreteA();
        IDoWork<KeyA, ConcreteA> instance = WorkFactory.getInstance().obtainInstance(a, c);
        instance.obtain(a, c);
}

obtainInstanceタイプを適切に推測するために、キーと val を取るように変更しました。

于 2012-05-17T02:01:55.780 に答える