2016-09-07 16 views
0

Genericについて学習し始めました。ここでは、グローバルobjの値をローカルobjの値に設定しようとしています。しかし、型変換エラーが発生しました。このエラーの原因は何ですか?ここで汎用型の型変換エラー

class GenUpperBound<T> 
{ 
    T obj; 
    public <T extends Number> void set(T obj) 
    { 
     this.obj=obj; 
    } 

    public static void main(String...q) 
    { 
     GenUpperBound<Integer> w=new GenUpperBound<>(); 
     w.set(10); 
    } 
} 

は誤りです....

GenupperBound.java:6: error: incompatible types: T#1 cannot be converted to T#2 
     this.obj=obj; 
      ^
    where T#1,T#2 are type-variables: 
    T#1 extends Number declared in method <T#1>set(T#1) 
    T#2 extends Object declared in class GenUpperBound 
1 error 

答えて

4

コンストラクタスコープの型パラメータ<T extends Number>皮革クラススコープ型のパラメータ<T>

0

あなたがそうでなければ、あなたのobjは、例えばString型のものであってもよいので、

class GenUpperBound<T extends Number> 

ようなあなたのクラスを宣言する必要があり、あなたすることができますStringにNumberを代入しません。

class GenUpperBound<T extends Number> 
{ 
    T obj; 
    public void set(T obj) 
    { 
     this.obj=obj; 
    } 

    public static void main(String...q) 
    { 
     GenUpperBound<Integer> w=new GenUpperBound<>(); 
     w.set(10); 
    } 
} 
1

はこれを試してみてください。それらの2つのTは同じタイプを表していません。

これは、コンストラクタ内の引数が、クラスがパラメータ化された型と異なる種類の可能性があるため、コードをコンパイルするのを拒否するためです。たとえば:

new GenUpperBound<String>(new Integer(1)); 

違いは、あなたがUにコンストラクタスコープタイプパラメータ名前を変更した場合に見はっきりことができます。

class GenUpperBound<T> { 

    T obj; 

    public <U extends Number> void set(U obj) { 
     this.obj=obj; 
    } 

    ... 
} 

は今、これはあまりにも、罰金コンパイルが、TUは明らかにを表します。


あなたがして、この問題を修正することができます:

class GenUpperBound<T extends Number> { 

    T obj; 

    public void set(T obj) { 
     this.obj=obj; 
    } 
... 
} 

今そこに二T型パラメータがありませんが、コンストラクタは、クラススコープ1を使用しています。この場合、new GenUpperBound<String>(new Integer(1));のような文はコンパイルされません。なぜなら、引数がインスタンスがパラメータ化された型と同じ型ではないからです。