2014-10-19 93 views
2

我的代碼如下所示:爲什麼Java模板約束將約束類型限制爲返回語句中的擴展類型?

public class Something<T extends Thing> { 

    private T theThing; 

    public Something(T aThing) { 
     theThing = aThing; 
    } 

    public T getTheThing() { 
     return theThing; 
    } 
} 

然後,冥冥中,我寫這篇文章:

Something something = new Something<SpecialThing>(new SpecialThing()); // SpecialThing extends Thing 
SpecialThing specialThing = something.getTheThing(); // Error: getTheThing() returns object of type Thing instead of SpecialThing! 

爲什麼我沒有得到theThingSpecialThing,但作爲一個Thing呢?

事情類:

public abstract class Thing { 
} 

SpecialThing類:

public class SpecialThing extends Thing { 
} 
+1

提供Thing和SpecialThing類代碼。 – SMA 2014-10-19 13:51:29

回答

4

的原因是,您使用的是原始類型引用您的Something。這意味着Java唯一可以肯定地說的是,返回的類型擴展爲Thing,所以這就是你所得到的類型。

添加類型參數像這樣返回SpecialThing

Something<SpecialThing> something = new Something<SpecialThing>(new SpecialThing()); 
SpecialThing specialThing = something.getTheThing(); 
3

因爲你沒有指定變量聲明的類型。你可能用SpecialThing實例化了它,但那不是你記得它的方式。

你會注意到它在你使用它的時候會起作用。

Something<SpecialThing> something = new Something<SpecialThing>(new SpecialThing()); 

與定義ArrayList t = new ArrayList<String>();相同。這仍將被視爲ArrayList<Object>,而不是ArrayList<String>

JavaDocs on raw types