【发布时间】:2013-11-20 15:34:48
【问题描述】:
对于此问题中任何不好的英语语言,请提前道歉。
我想创建一种工厂,它只能创建由具体工厂实例类实现的列表中定义的类的实例。首先,我定义了这个接口:
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 只是一个“标记包装器”接口,它使用泛型来定义一个“允许”由我的工厂创建的类实例。
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)
我想我错过了一些关于泛型的类型推断的东西。
谁能解释一下 create 方法签名在这种情况下不适用以及如何解决?
提前感谢您抽出宝贵时间。
【问题讨论】:
-
这里
VALUES_ID枚举的作用我不是很明白。目前,您的allowedValues地图仅包含一个条目。你能解释一下吗?顺便说一句,你为什么不让你的类自己通用? -
在示例中是的,它包含一个唯一的枚举值。这只是为了简化。枚举和 EnumMap 旨在包含多个值(对于枚举)和 AllowedValue 对象(对于 EnumMap)
-
那么您是否遍历枚举
values()以向地图添加条目?你能发布你的getAllowedValues的实际样子吗? -
如果我没记错的话,getAllowedValues 方法在我的 BasicValueSystem 类示例中
-
对不起,我的意思是,你能把它扩展一下。目前尚不清楚您维护地图的方式。你想每个枚举都有一个映射,包含所有允许的值吗?如果单个枚举值有多个允许值怎么办?
标签: java generics type-inference