ジェネリック型パラメーターを推測するためのJavaのルールをナビゲートするのに問題があります。オプションのリストパラメータを持つ次のクラスを検討してください。
import Java.util.Collections;
import Java.util.List;
public class Person {
private String name;
private List<String> nicknames;
public Person(String name) {
this(name,Collections.emptyList());
}
public Person(String name,List<String> nicknames) {
this.name = name;
this.nicknames = nicknames;
}
}
私のJavaコンパイラは次のエラーを出します:
Person.Java:9: The constructor Person(String, List<Object>) is undefined
ただし、Collections.emptyList()
は、<T> List<T>
ではなく、List<Object>
型を返します。キャストを追加しても役に立たない
public Person(String name) {
this(name,(List<String>)Collections.emptyList());
}
利回り
Person.Java:9: inconvertible types
emptyList()
の代わりにEMPTY_LIST
を使用する
public Person(String name) {
this(name,Collections.EMPTY_LIST);
}
利回り
Person.Java:9: warning: [unchecked] unchecked conversion
次の変更により、エラーはなくなります。
public Person(String name) {
this.name = name;
this.nicknames = Collections.emptyList();
}
誰も私がここで実行しているタイプチェックルールとそれを回避する最良の方法を説明できますか?この例では、最終的なコード例で問題ありませんが、クラスが大きい場合は、コードを複製せずにこの「オプションのパラメーター」パターンに従ってメソッドを記述できるようにします。
追加クレジット:emptyList()
ではなくEMPTY_LIST
を使用するのが適切な場合
あなたが遭遇している問題は、メソッドemptyList()
がList<T>
を返したとしても、タイプを提供していないため、デフォルトでList<Object>
を返すことです。 typeパラメーターを指定し、次のようにコードを期待どおりに動作させることができます。
public Person(String name) {
this(name,Collections.<String>emptyList());
}
これで、直接代入を行うとき、コンパイラはジェネリック型パラメーターを見つけ出すことができます。型推論と呼ばれます。たとえば、これを行った場合:
public Person(String name) {
List<String> emptyList = Collections.emptyList();
this(name, emptyList);
}
その後、emptyList()
呼び出しはList<String>
を正しく返します。
使用したい:
Collections.<String>emptyList();
EmptyListの内容のソースを見ると、実際には単に
return (List<T>)EMPTY_LIST;
emptyListメソッドには次のシグネチャがあります。
public static final <T> List<T> emptyList()
Word Listの前の<T>
は、結果が割り当てられる変数の型からジェネリックパラメーターTの値を推測することを意味します。したがって、この場合:
List<String> stringList = Collections.emptyList();
その後、戻り値はList<String>
型の変数によって明示的に参照されるため、コンパイラーはそれを把握できます。この場合:
setList(Collections.emptyList());
コンパイラーがジェネリック型を判別するために使用する明示的な戻り変数はないため、デフォルトはObject
になります。