为什么创建带番石榴的工厂会出现类型不匹配错误?

时间:2012-10-24 16:23:43

标签: java guava

我正在尝试创建一个工厂(从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>>

4 个答案:

答案 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();
}