我有以下代码:
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类型中获取(捕获#3-of?extends AbstractKey,捕获#4-of?extends AbstractClass)的方法不适用于参数(KeyA,ConcreteA)
还有其他办法吗?如果省略
中的类型参数IDoWork<? extends AbstractKey, ? extends AbstractClass> instance =...
如果我从IDoWork
删除类型参数...它可以工作,但我收到警告。有没有办法解决这个问题。?我知道我可以从界面中删除类型参数,这将解决问题,但我觉得使用泛型以便不必进行投射很方便+它为代码带来了清晰度,因为它清楚地看到每个类的内容使用。 Depencendy注入是不可能的,因为它在我所在的代码库中不可用。
答案 0 :(得分: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,以正确推断类型。