以下の一般的な方法でプログラムを考えてみましょう:
class GenericTest {
int i;
}
public class GenericMethod {
public <T> List<T> addList(T t, T t1) {
List<T> list=new ArrayList<T>();
list.add(t);
list.add(t1);
return list;
}
public <T> List<T> addList(T t, T t1, List<T> l) {
List<T> list=new ArrayList<T>();
list.add(t);
list.add(t1);
list.addAll(l);
return list;
}
public static void main(String[] args) {
GenericMethod gm=new GenericMethod();
List l=gm.addList(new Integer(42), "java"); //Line 21
System.out.println(l);
List<Object> list = new ArrayList<Object>();
list.add(false);
List l2 = gm.addList("java", new Integer(42), list); //Line 25
System.out.println(l2);
GenericTest gt = new GenericTest();
List l3 = gm.addList("java", gt); //Line 28
System.out.println(l3);
List l4 = gm.addList(gm, gt); //Line 30
System.out.println(l4);
List lst = new ArrayList();
lst.add(new Object());
List l5 = gm.addList("java", new Integer(42), lst); //Line 34
System.out.println(l5);
System.out.println(l5.get(0));
}
}
参考リンクを経由することでJavaのジェネリック-行動を混乱私はそれをinferingています、
この方法は、文字列と整数の両方で呼び出されるので、21行目では、それは同じT.のためのオブジェクトとメソッドを呼び出しリストには、オブジェクトを入力しているようにライン25のために行く、それは他のタイプの意志で一覧を呼び出すT.ためのオブジェクトでメソッドを呼び出しますエラーが発生します。私の推論は正しいですか?
私が思ったことができないことについてです
1)28行目の文字列とクラスが渡されたときに、
2)二つの異なるクラスが渡されたライン30を、
3)リストをタイプせずに宣言ライン34は、引数として渡されます。
缶誰もが私の理解をクリアするために彼らの知識を共有しています。任意の助けいただければ幸い!ありがとう!
他のタイプの一覧を呼び出すと、エラーが生成されます。私の推論は正しいですか?
はい; あなたは渡すことはできませんList<String>
例えば、そこに。一般的には2番目のADDLIST方法の目的は、単に間違っています。正しい署名はこれです:
public <T> List<T> addList(T t1, T t2, List<? extends T> list)
注意? extends
構文を。あなたが行うすべてがリストから読み込んだ場合、それを追加しない理由はありません。Tのいくつかの特定のサブタイプの一覧は、Tsは含むことが保証されます。すべての違いがあります理由:あなたがしたい場合はどうADDこのリストに?TがあるとしましょうNumber
、あなたはのリストを渡しますInteger
。ダブルナンバーです。ではList<T> list
、あなたは呼び出すことができlist.add(5.0)
、それが整数のリストにダブルスを入れ、コンパイルして実行します。List<? extends T>
(追加しようとしない限り、追加の呼び出しは、常にコンパイルエラーでnull
動作することになります)。読書のために、あなたが得るT
あなたが呼んでいるかどうか、アウトのget
上List<? extends T>
かList<T>
、それは問題ではありません。
1)28行目の文字列とクラスが渡されたときに、
いいえ、あなたは、String型とタイプGenericTestのインスタンスのインスタンスを渡しています。文字列はGenericTest限り、Aクラスがあるだけのようです。文字列は特別なものではありません。これは、ライン21で通話とまったく同じシナリオです:あなたは、2式を渡しています。オブジェクトタイプXの一方と従ってオブジェクトタイプYの他方は、T
2つの渡されたインスタンス間:最も特定の共有タイプ(タイプのセット、おそらく、いわゆるLUB型)であることがinferencedれます。ライン21の場合、Integer
およびString
最も具体的な共有型の単純であるObject
(、技術的なことを、実際にそのLUBタイプObject & Serializable
が、ほとんどここでの問題ではないということ)。28行目では、間の最も特定の共有タイプだString
とGenericTest
まだあるObject
、ないの違いは。
2)二つの異なるクラスが渡されたライン30を、
上記を参照; 正確に同じような状況。最も具体的には、間のタイプを共有GenericTest
してGenericMethod
いますObject
。
3)リストをタイプせずに宣言ライン34は、引数として渡されます。
表現lst
のライン34内には、「生」タイプですArrayList
。あなたは生の型を使用する場合、2つの処理が行われます[1]は、コンパイラがそう、あなたが生の型を使用している、と[2]はかなりのジェネリックテストとチェックがすべて任意の生の型に関連するすべての呼び出しのために無効になっていることを警告します、コンパイラは、ちょうどこれが起こるようになります。
ジェネリック医薬品は、コンパイラの想像力の案出していることを覚えておいてください。そのポイントは、あなたのコードが壊れていることを伝えるためのコンパイラです。それで全部です。