2014-10-31 16 views
1
Class X{ 
    Class<B> object; 
    public setObject(Class<B> a){....} 
} 

Interface B{} 
Interface C extends B {} 

我實例X這樣的,類型注射在Spring XML和Java配置

X x = new X(); 
x.setObject(C.class); 

當我建立它抱怨需要Class<B>代碼中發現Class<C>。由於C擴展B,我不能使用C.class嗎?如果有的話,可以解釋一下爲什麼?

我做了同樣的事情,使用Spring的基於XML的bean創建它工作得很好。豆的定義是

<bean id="dummy" class="X"> 
<property name"object" value="C"> 
</bean> 

這工作得很好。我沒有得到爲什麼在Java中實例化會失敗。

回答

0

這不是有效的Java代碼

它的工作原理,因爲對於參數進行類型擦除<>

java字節碼看起來與

相同
class X{ 
    Class object; 
    public void setObject(Class a){....} 
} 

interface B{} 
interface C extends B {} 

它丟失了類型檢查信息,它只在編譯時使用。

您可以使用此使它在代碼工作:

class X{ 
    Class<? extends B> object; 
    public void setObject(Class<? extends B> a){....} 
} 

interface B{} 
interface C extends B {} 
1

The same way a List<Dog> is not assignable to List<Animal>,Class<C>不可分配給Class<B>,即使CB的子類型。

使用XML配置,您忽略了所有類型的安全規則。就好像您使用的是原始類型一樣,每個參數化類型的用法都被刪除。 A Class<C>變成Class並且Class<B>變成Class。 A Class可分配給Class

0

這是正常的,setObject(Class<B>)不會拿Class<C>參數, 爲同樣的原因,someMethod(List<Object>)不會拿List<Integer>參數: List<Integer>不是List<Object>一個子類,即使IntegerObject子類。

要使其工作,你可以在你的方法簽名改成這樣:

public setObject(Class<? extends B> a) {....}