对于这个问题中的任何不良英语,请提前抱歉。
我想要创建一种工厂,它只能创建由具体工厂实例类实现的列表中定义的类的实例。首先,我定义了这个界面:
public interface ValuesSystem {
public interface AllowedValue<T extends Class<? extends SystemValue>>{};
AllowedValue<Class<? extends SystemValue>> getAllowedValue(Enum<?> id);
Map<? extends Enum<?>, AllowedValue<Class<? extends SystemValue>>> getAllowedValues();
<T extends SystemValue> T create(AllowedValue<Class<T>> allowedClass, ValueData data) throws InvalidValueException;
}
接口AllowedValue只是一个“标记包装器”接口,使用泛型来定义我的工厂“允许”创建的Class实例。
getAllowedValue是一个方法,用于从我允许的类“列表”中获取一个包装的允许类实例,使用实现此接口的具体类的内部枚举(具体类的示例将会出现)。
create方法旨在最终创建allowedClass参数中给出的允许的Class实例的实例。
以下是实现此接口的具体类的示例:
public class BasicValueSystem implements ValuesSystem {
public BasicValueSystem() {
super();
allowedValues = (Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>>) getAllowedValues();
}
public static enum VALUES_ID {
MODIFIER
}
private static Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>> allowedValues;
private class BasicAllowedValue<T extends Class<? extends SystemValue>>
implements AllowedValue<Class<? extends SystemValue>> {
}
@Override
public <T extends SystemValue> T create(
AllowedValue<Class<T>> allowedClass, ValueData data)
throws InvalidValueException {
if (!(allowedClass instanceof BasicAllowedValue)) {
throw new InvalidValueException();
}
return null;
}
@Override
public AllowedValue<Class<? extends SystemValue>> getAllowedValue(Enum<?> id) {
return allowedValues.get(id);
}
@Override
public Map<? extends Enum<?>, AllowedValue<Class<? extends SystemValue>>> getAllowedValues() {
Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>> allowed = new EnumMap<VALUES_ID, AllowedValue<Class<? extends SystemValue>>>(VALUES_ID.class);
allowed.put(VALUES_ID.MODIFIER, new BasicAllowedValue<Class<ModifierValue>>());
return allowed;
}
}
目前,create方法返回null,但问题出在其他地方,这不是我的问题
当我尝试使用以下代码创建一个“允许”值实例的实例时,会出现问题:
BasicValueSystem bvs = new BasicValueSystem();
AllowedValue<Class<? extends SystemValue>> allowed = bvs
.getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());
编译器告诉我:
The method create(ValuesSystem.AllowedValue<Class<T>>, ValueData) in the type BasicValueSystem is not applicable for the arguments (ValuesSystem.AllowedValue<Class<? extends SystemValue>>, ModifierValueData)
我想我遗漏了一般关于泛型的类型推断的事情。
任何人都可以解释一下,创建方法签名在这种情况下是不适用的,以及如何解决它?
提前感谢您抽出宝贵时间。
答案 0 :(得分:3)
请注意,public interface AllowedValue<T extends Class<? extends SystemValue>>
没有多大意义。 T
唯一有效的类型是Class<? extends SystemValue>
,因为类Class
是最终的,不能有子类。所以你可以用interface AllowedValue<Class<? extends SystemValue>>
替换它而不改变语义,但你真正的意思是什么(imho)是interface AllowedValue<T extends SystemValue>
。不要在类型签名中弄乱Class
。接口仍然可能有方法引用Class<T>
然后。
public interface ValuesSystem {
public interface AllowedValue<T extends SystemValue>{};
AllowedValue<? extends SystemValue> getAllowedValue(Enum<?> id);
public <T extends SystemValue> T create
(AllowedValue<T> allowedClass, ValueData data);
}
相应地调整实施,BasicAllowedValue
变为
private class BasicAllowedValue<T extends SystemValue> implements AllowedValue<T>
然后您使用代码的问题就会消失。
BasicValueSystem bvs = new BasicValueSystem();
AllowedValue<? extends SystemValue> allowed = bvs
.getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());
将编译。
请注意,如果AllowedValue
仍然是一个没有方法的标记界面,则没有必要,Class<T>
已经履行了这个角色。这样做也会起作用:
public interface ValuesSystem {
Class<? extends SystemValue> getAllowedValue(Enum<?> id);
public <T extends SystemValue> T create(Class<T> allowedClass, ValueData data);
}
和
BasicValueSystem bvs = new BasicValueSystem();
Class<? extends SystemValue> allowed = bvs
.getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());