3

I'm trying to create a factory (generating new instances from a String parameter).

I've got a Monster class (the superclass) and Robot1 class (extends Monster).

My factory declares :

private static final ImmutableMap<String, Class<? extends Monster>> DISPATCHER = ImmutableMap.of("robot1", Robot1.class);

But I get :

Type mismatch: cannot convert from ImmutableMap<String,Class<Robot1>> to ImmutableMap<String,Class<? extends Monster>>
4

4 回答 4

6

做就够了

private static final ImmutableMap<String, Class<? extends Monster>> DISPATCHER = 
   ImmutableMap.of("robot1", (Class<? extends Monster>) Robot1.class);

Java 倾向于假设您想要最具体的类型,即使您不想要。这种向上转换不会引起任何警告,因为它非常安全——它只是告诉 Java 编译器您想要更通用的类型。

于 2012-10-24T16:48:56.523 回答
2

这是因为,您可以使用 的任何子类型Monster代替Class<? extends Monster>,这实际上不是Robot. 因此,编译器不允许使用类型参数引用具有Class<? extends Monster>更具体类型参数的实例,因为这可能会在运行时失败。

对于EG: - Class<? extends Monster>实际上可以是Class<Zomby>,当然Class<Robot>不能转换为。这就是Class<Robot>不能隐式转换为的原因Class<? extends Monster>

这与您不能这样做的情况类似:-

List<Animal> dogList = new ArrayList<Dog>();

同样,由于您可以在 中添加任何类型的动物dogList,因此您不能在 RHS 上使用更具体的类型参数

  • 此检查仅在编译时完成,编译器确定这可能在运行时失败,因此它不允许这样做。
于 2012-10-24T16:27:32.810 回答
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);
于 2012-10-24T16:27:48.907 回答
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();
}
于 2012-10-25T09:25:23.210 回答