2017-01-12 17 views
3

私は次のようなエラーがあります。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を持つように宣言されていることです。

あなたがBの型パラメータがA<String>から継承されたgetT()メソッドの戻り値の型とは何の関係もないように、彼らは、同じ名前を持っているにもかかわらず、B Sの型パラメータがA区別される 'はb1を示しています。ただし、RAWタイプを使用すると、そのスーパータイプを含めて、そのタイプの完全なイレージャーが得られます。

Aの型パラメータは無制限なので、消去はタイプObjectを生成するため、タイプはb2.getT()です。もちろんObjectStringに割り当てられません。

あなたは、少なくとも2つの方法でこれを解決することができます

  1. b2の生タイプを使用しないでください。型パラメータについて気にしない場合は、B<?>を使用してください。または

  2. クラスBの型パラメータを削除します。それはあなたの例では何のためにも使用されていないので、これは最もきれいなことです。そのスーパークラスが汎用であるという理由だけで、Bを指定する必要はありません。

+0

実際には、OPが記述しているエラーは発生しませんが、OPが現在のエラーを修正した後にエラーが発生します。 – PMARINA

+0

@PMARINAに従っていません。あなたはOPのコードで、 'b2.getT()'の戻り値の型は 'Object'ですか?コンパイルエラーを説明するのは難しいでしょう。それともそうだと私の説明に同意しないのですか?その場合は、共有してください。 'b1'が' B '型のときに、なぜ' b1.getT() 'が' String'を返すのか説明できます。 –

+0

私はあなたの答えに同意しません。これは現在のエラーがパラメータによって引き起こされていると述べています。問題は、getT()を呼び出すとT型のオブジェクトを返さなければならないということです。これは、入力が常にstring型であることによって解決されるべきではありません。代わりに、OPはtoString()メソッドを追加し、getT()ではなくそのメソッドを呼び出す必要があります。 OPはStringだけで作業するための余分なクラスを必要とせず、他のデータ型の使用を計画していない限りT()というタイトルではないため、Stringを常に使用するソリューションは愚かです。 – PMARINA

-1

問題ここgetT()がオブジェクトを返すことです。何をする必要がある(そう宣言はT t3 = b1.getT();T t4 = b2.getT();に出てくるか、単にTt3t4のためのタイプを変更する)Stringの面でTオブジェクトの値を与える方法toString()を実装しています。また

、あなたはあなたがb1.anyMethod()を呼び出すことができるか、他あなたがNullPointer Exceptionを買ってあげる前に、何かにBを初期化する必要があり、次の代わりB.

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

ためのあなたが持っているコード注を行う必要があります。

+1

私はあなたがその点を逃したと思う。ここでの基本的な質問は、なぜ 'b1'(' type'の)で呼び出されたときに 'String'を返すとしても、' getT() 'が' b2'(B型の) B ))。 'toString()'をオーバーライドすることの提案は*非連続*です。他のタイプのオブジェクトの文字列表現であると考える理由はありません。 –

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(); 
} 
関連する問題