これを考えるとList<Employee>:
List <Employee> empList=new ArrayList<Employee>();
追加しようとしたときStudent:
l.add(0,new Student(1,2,3));
リストはこれをどのように解決し、コンパイル エラーを表示しますか?
実際にListは、チェックを行うのは具体的にはではなく、コンパイラです(あなたが示唆したように)。
は、次のList2 つの情報を提供するだけです。
E型Listがパラメーター化される型があります。
public interface List<E> extends Collection<E>
メソッドaddは type のオブジェクトを受け入れますE:
boolean add(E e);
をビルドすると、コンパイラList<Employee>はそれ以外 で呼び出すことができないことを認識し、それを試みた場合にコンパイラ エラーが発生します。addEmployee
また、実行時にそのようなチェックがないことにも注意してください。したがって、コンパイラによって行われたチェックを何とか「こっそり」(たとえば、 raw typeを使用して) できた場合、あらゆる種類の間違ったことを行うことができList、ランタイムは問題を検出しません (試してみるまで)非ジェネリックな方法で「間違った」型にアクセスするため)。
List<Employee> empList = new ArrayList<Employee>()
上記の場合、empListに。のインスタンスのみが含まれるように指定したためですEmployee。
Employeeまたはから派生していない他のインスタンスタイプを追加しようとしたときに文句を言うのは、コンパイラの責任です。これは、コンパイル中に、このリストに追加できるインスタンスのタイプを決定するのに十分な情報をコンパイラーに提供したためです。したがって、コンパイラは、add()メソッドが常にのインスタンスを期待するか、またはから派生したインスタンスを期待することを知ってEmployeeいStudentます。したがって、あなたの場合のエラー。
ジェネリックスを使用したもう1つの興味深い結果はget()、このリストの要素を試してみた場合です。そのときのコンパイラは、リストから取得しようとしている要素がEmployeeクラスである必要があることも認識しています。したがって、不正なキャストを実行した場合(たとえば、から返されたオブジェクトをにキャストした場合get())Student、コンパイラは再び文句を言います。
次の記事は、この概念を理解するのに役立つ可能性があります。
Generics