2012-10-24 30 views
3

我想創建一個工廠(從一個String參數生成新的實例)。爲什麼使用番石榴創建工廠時會出現類型不匹配錯誤?

我有一個怪物類(超類)和Robot1類(擴展怪物)。

我廠聲明:

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>> 

回答

2

這是因爲,你可以有Monster任何亞型代替Class<? extends Monster>,這實際上不是一個Robot。因此,編譯器不允許將帶有Class<? extends Monster>的引用作爲類型參數傳遞給具有更多特定類型參數的實例,因爲這可能會在運行時失敗。

對於E.G: -Class<? extends Monster>可以是實際上Class<Zomby>,這當然Class<Robot>的不能轉換到。 這是,Class<Robot>不能被隱式轉換爲Class<? extends Monster>

這是類似的情況,在這裏你可以這樣做的原因: -

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

再次,因爲你可以在dogList添加任何類型的動物,所以你不能在RHS上有更具體的類型參數

  • 這個檢查只在編譯時完成,編譯器確定這可能會在運行時失敗,所以它不允許這樣做。
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); 
+0

你爲什麼要加一箇中間投? –

+0

@RohitJain中間劇組需要清除泛型以標記它可以接受任何事物,然後轉換爲具體的。 –

+0

好的。是的,這是需要的。剛剛在'Number'和'Integer'上測試過。這是我不知道的。 +1 :) –

6

這足以做

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

的Java傾向於假設你最想要的特定類型的可能,即使你不知道。這個upcast不會產生任何警告,因爲它是完全安全的 - 它只是告訴Java編譯器你想要更普通的類型。

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