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 类型中的方法 gain(capture#3-of ? extends AbstractKey, capture#4-of ? extends AbstractClass) 不适用于参数 (KeyA, ConcreteA)

还有另一种方法吗?如果省略中的类型参数

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

如果我从IDoWork... 中删除类型参数,它可以工作,但我会收到警告。有没有办法解决这个问题。?我知道我可以从接口中删除类型参数,这将解决问题,但我发现拥有泛型以便不必进行强制转换很方便 + 它使代码更加清晰,因为可以清楚地看到每个类用途。依赖注入是毫无疑问的,因为它在我所在的代码库中不可用。

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为获取键和值,以正确推断类型。

于 2012-05-17T02:01:55.780 回答