我正在尝试创建一个工厂(从String参数生成新实例)。
我有一个Monster类(超类)和Robot1类(扩展了Monster)。
我的工厂声明:
private static final ImmutableMap<String, Class<? extends Monster>> DISPATCHER = ImmutableMap.of("robot1", Robot1.class);
但我明白了:
Type mismatch: cannot convert from ImmutableMap<String,Class<Robot1>> to ImmutableMap<String,Class<? extends Monster>>
答案 0 :(得分:6)
足够
private static final ImmutableMap<String, Class<? extends Monster>> DISPATCHER =
ImmutableMap.of("robot1", (Class<? extends Monster>) Robot1.class);
Java倾向于假设您希望尽可能使用最具体的类型,即使您不这样做。这个upcast不会产生任何警告,因为它非常安全 - 它只是告诉Java编译器你想要更通用的类型。
答案 1 :(得分:2)
这是因为,您可以使用Monster
的任何子类型代替Class<? extends Monster>
,这实际上不是Robot
。因此,编译器不允许将带有Class<? extends Monster>
的引用作为类型参数添加到具有更具体类型参数的intance,因为这可能在运行时失败。
对于E.G: - Class<? extends Monster>
实际上可以是Class<Zomby>
,当然Class<Robot>
无法转换为Class<Robot>
。
这就是Class<? extends Monster>
无法隐式转换为List<Animal> dogList = new ArrayList<Dog>();
这与您无法做到的情况类似: -
dogList
同样,由于您可以在{{1}}中添加任何类型的动物,因此,您无法在RHS上添加更具体的类型参数
答案 2 :(得分:2)
问题是Robot1.class
会将Class<Robot>
返回给您,Class<? extends Monster>
无法投放到ImmutableMap<String, Class<? extends Monster>> DISPATCHER =
(ImmutableMap<String, Class<? extends Monster>>)(ImmutableMap<?, ?>)ImmutableMap.of(
"robot1", Robot1.class);
所以你需要为这种情况添加特定的演员。
{{1}}
答案 3 :(得分:1)
我找到了一种工作正常的方式,没有任何演员:
private static final ImmutableMap<String, Class<? extends Monster>> DISPATCHER;
static {
ImmutableMap.Builder<String, Class<? extends Monster>> builder = ImmutableMap.builder();
// Monsters types list
builder.put("robot1", Robot1.class);
DISPATCHER = builder.build();
}