2017-01-12 35 views
3

在Android Studio中,我有以下錯誤:Java的泛型類型的繼承錯誤

java: incompatible types: java.lang.Object cannot be converted to java.lang.String

我認爲b1和b2應該表現相同,但他們都沒有。

有沒有辦法讓他們表現相同(不改變他們的課程類型)?

下面是代碼類型:

public class Test 
{ 
    class A<T> 
    { 
     T t; 
     T getT() 
     { 
      return t; 
     } 
    } 
    class AS extends A<String> 
    { 

    } 
    class B<T> extends AS 
    { 

    } 

    B<Object> b1; 
    B b2; 

    public void test() 
    { 
     String t3 = b1.getT(); 
     String t4 = b2.getT(); 
    } 
} 
+0

你可以複製並粘貼代碼,以便我可以抓取我的答案代碼示例? –

+0

我編輯了我的答案,所以代碼是可複製的。 :) –

+0

更正,可以用'javac'重現,但不能用'eclipsec'重現。邏輯保持不變;您使用'B'的已刪除版本,您使用'A'的已刪除版本,因此它會根據[JLS]返回一個對象(https://docs.oracle.com/javase/specs/jls/se7/html/jls -4.html#JLS-4.8)。畢竟,這是一個關於http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it的玩笑。 –

回答

1

的問題是,B是參數化類型,但b2被宣佈爲具有B作爲其類型。

您展示與b1B的類型參數是從A不同的,即使他們有相同的名字,這樣B的類型參數無關與A<String>繼承了getT()方法的返回類型。但是,如果使用原始類型,則會得到該類型的完整刪除,包括其超類型。

由於A的類型參數是無界的,因此其擦除產生的類型爲Object,因此這是b2.getT()的類型。當然,Object不可轉讓給String

可以在至少兩種方式解決此問題:

  1. 不要使用原始類型b2。如果您不關心其類型參數,請使用B<?>。或者,

  2. 刪除類B的類型參數。它不用於你的例子中的任何事情,所以這將是最乾淨的事情。僅僅因爲它的超類是通用的,並不意味着B必須是。

+0

實際上,這不會導致OP描​​述的錯誤,儘管這會在OP修復當前錯誤 – PMARINA

+0

後導致錯誤,我不會跟着你,@ PMARINA。你不同意在OP的代碼中,'b2.getT()'的返回類型是'Object'嗎?然後,您將很難解釋編譯器錯誤。或者你不同意我爲什麼這麼解釋?在這種情況下,請分享。確保你可以解釋爲什麼'b1.getT()'確實返回'String',但是'b1'有類型'B '。 –

+0

我不同意你的答案,其中指出當前錯誤是由參數引起的。問題是調用getT()應該返回一個類型爲T的對象。這不應該通過始終使輸入爲字符串類型來解決。相反,OP應該添加一個toString()方法並調用它,而不是getT()。總是使用String的解決方案是愚蠢的,因爲OP不需要額外的類來完成字符串處理,並且不會爲T()標題,除非他/她計劃使用其他數據類型。 – PMARINA

-1

的這裏的問題是,getT()返回的對象。你需要做的就是實現的方法toString()給出的方面T對象的值String(或只是改變類型t3t4T這樣的聲明就出來T t3 = b1.getT();T t4 = b2.getT();)。

此外,你應該做到以下幾點,而不是你有B.

B<T> b1; 
B<T> b2; 

請注意,您需要初始化B到東西,你可以撥打b1.anyMethod(),否則你會得到一個NullPointer Exception之前的代碼。

+1

我認爲你錯過了這一點。這裏的基本問題是*爲什麼*當在'b2'('B'類型)上調用getT()時返回Object,即使它在'b1'上調用時返回'String' B ')。重寫'toString()'的建議是* non-sequitur *;沒有理由認爲它是一個想要的其他類型的對象的字符串表示。 –

0

我認爲B沒有模板對象是一個不完整的類,而不是B<Object>。這就是爲什麼當你打電話給它getT()你實際上叫A.getT()

爲什麼在下面的代碼中,只有String t3 = b2.getT();無法編譯。

static class A<T> 
{ 
    T t; 
    T getT() 
    { 
     return t; 
    } 
} 

static class AS extends A<String> {} 

static class B<T> extends AS {} 

static class C extends B<Object> {} 

static A a; 
static B<Object> b1 = null; 
static B b2 = new B(); 
static C c = new C(); 

static void test() 
{ 
    Object tt = a.getT(); 
    String t2 = b1.getT(); 
    String t3 = b2.getT(); 
    String t4 = c.getT(); 
}