2016-10-13 7 views
0

次のコードはなぜ使用できないのですか?Javaの汎用クラスメンバーを返すパラメータ化されたメソッド

class MyClass { 
    List<? extends Something> list; 
    <T extends Something> List<T> myFunc(T t) { 
     list = new ArrayList<T>(); // ok 
     list.add(t); // error 
     return list; // error 
    } 
} 

同じようにコードを修正するにはどうすればよいですか?すなわち、クラスメンバーlistは、Somethingのサブクラスであり、myFunc()のサブクラスであるオブジェクトのみを受け入れますか?

+0

:あなたは後者の方法で物事のためのList<T>として作成されたオブジェクトを使用したい場合

、あなたは、それを指すようにタイプList<T>の変数を維持するために、このようなものが必要あなたはクラスレベルでそれを行う必要があります。つまり、 'list'をローカル変数にして、' List <? 'の代わりに 'List list'を使用してください。 Something> list'を拡張します。 – ordonezalex

答えて

2

一般的な<T>の宣言は、クラスレベルで行うことができます。

これはワイルドカード?を型引数として使用できないためです。

ワイルドカードは、一般的なメソッド呼び出しのための型引数、ジェネリッククラスのインスタンスの作成、または

だから私は何を取得するJavaは知らないだろうということであるスーパータイプとして使用されることはありません<T extends Something>、そのそれを拡張するコンテキストがあっても、それが同じタイプであることを保証することはできません。

解決策は、クラスレベルでジェネリックを宣言します。私はそれが役に立てば幸い

class Abc <T extends Something>{ 
    List<T> list; 
    List<T> myFunc(T t) { 
     list = new ArrayList<T>(); // ok 
     list.add(t); 
     return list; 
    } 
} 

:私たちがしなければ

は、それが動作する可能性があります。

+0

よろしくお願いいたします。しかし、MyClassを宣言するときにジェネリック型を早期に設定したくない。ジェネリック型は、myFunc()が呼び出されるまで認識されません。 – user1589188

0

Tタイプパラメータは、どこにでも使用する前に定義する必要があります。理想的には、クラス宣言で定義する必要があります。あなたはクラス内の多くの場所でそれを使用しているからです。 Tがメソッドスコープでのみ使用されている場合は、メソッドシグネチャで定義することができます。あなたはアッパーを変更することはできません

<T extends Something>無制限<?>型インスタンスを有界。

つまり、List<?>(無制限のリスト)とList<T extends Something>に要素を追加することはできません。

これを機能させたい場合は、リストの下限タイプのパラメータを使用できます。

class MyClass<T super Something> { 
    List<T super Something> list; 
    <T super Something> List<T> myFunc(T t) { 
     list = new ArrayList<T>(); // ok 
     list.add(t); 
     return list; 
    } 
} 
+0

はい、ありがとう、ありがとう。私は '?'をリストに使用したくないのですが、タイプのないリストも使用したくありません。そして、Tがメソッドから来るだけでクラスではない場合、List listを使う方法はありません。 – user1589188

0

List<? extends Something>tT型を持つ入力したlist.add(t);listので、あなたが行うことができない、とT?が表す未知のタイプのサブタイプであるかどうかを知る方法はありません。

listList<? extends Something>型を持つと、リストの戻り値の型がList<T>で、List<? extends Something>List<T>であるかどうかを知る方法がないため同様に、あなたはreturn list;を行うことはできません。

List<T>を変数に入れて、それがList<T>であり、List<T>のように使用しようとしていることを知っていると思います。しかし、それはどのように動作するのではありません。listのタイプはList<? extends Something>です。何を入れても、変数の型は変更されず、変数の使用方法はコンパイル時の型に基づいていなければなりません。私が思う

<T extends Something> List<T> myFunc(T t) { 
    List<T> tempList = new ArrayList<T>(); 
    list = tempList; 
    tempList.add(t); 
    return tempList; 
} 
関連する問題