こんにちは。Java Goldを勉強しているのですが、ジェネリクス(総称型)が全然分かりません。しかし、ジェネリクスが使用されているList型やMap型は使うことができています。しかし、このままでは「よく分からないものを使っている」というとてもよろしくない状態です。
そこで今回は、Listインターフェースの中身を探検しながら、ジェネリクスを勉強してみたいと思います。ジェネリクスがよくわからない初心者の方のヒントになると幸いです。
ジェネリクス(総称型)とは
最もジェネリクスに親しみを感じられるのはListだと思います。
List<String> list = new LinkedList<String>();
ここにある変数listは、「String型を扱うListが型である」と言えます。しかし、Listが扱えるのは何もString型だけではありませんよね。
List<Integer> list2 = new LinkedList<Integer>(); List<Boolean> list3 = new LinkedList<Boolean>();
なんてこともできたと思います。これらから分かるように、ジェネリクスとは
- < >の中に好きな型を入れられる仕組み
と理解することができます(※プリミティブ型は不可ですが)。このように、包括的にいろいろな型を扱えるので、総称型と言われたり、型パラメータと言われたりします。それでは、どのようにしてジェネリクスが生まれたのか、またどのようにして好きな型を入れる仕組みが成り立っているのかを見ていきます。
ジェネリクス(総称型)の利点
ジェネリクスの利点は好きな型を入れられる以外にも、型の安全性を保証できる点が利点です。これは、ジェネリクスが無い時代のListを見てみるとよく理解できます。ジェネリクスが導入される前のListは以下のようなものでした。
List list = new LinkedList();
このListの怖いところは、型がない点です。Stringでもintでも、好きなオブジェクトを入れることができます。
List list = new LinkedList(); list.add("hello"); list.add(12345);
一見便利ですが、もちろんバグの温床でした。中に何の型が入っているのか分からないのです。怖くて取り出せませんし、だからといってずっとObject型で使うわけにもいきません。そこで、型を明確にするジェネリクスが導入されました。
ジェネリクス(総称型)の仕組み
それでは、なぜ複数の型を入れられるのか、List<>インターフェースを見ながら仕組みを探検します。eclipseで適当にListを作成し、F3を押すことで内部コードを見ることができます。そうすると、以下のようなインターフェース宣言になっていることが分かります。
public interface List<E> extends Collection<E> { Iterator<E> iterator(); boolean add(E e); E get(int index); E set(int index, E element); }
ここで出てくるEというのが型パラメータで、自由に型を決められる仕組みになります。まだこの時点では、Eにはどの型が入るのかが決まっていません。しかし、Eには必ず同じ型が入ります。そのため、実際にLinkの実装クラスをインスタンス化して際に初めて以下のように決まります。
//Stringの場合 public interface List<String> extends Collection<String> { Iterator<String> iterator(); boolean add(String e); String get(int index); String set(int index, String element); } //Integerの場合 public interface List<Integer> extends Collection<Integer> { Iterator<Integer> iterator(); boolean add(Integer e); Integer get(int index); Integer set(int index, Integer element); }
このように、指定した型がEをそっくりそのまま置き換える仕組みになっています。このためにどんな型でも柔軟に扱うことができていたのです。
まとめ
List<E>の中を探検しながらジェネリクス(総称型)を学びました。ジェネリクスにいまいち親しみが持てない状態から、ちょっと分かったかも?と思えるようお役に立てていたら幸いです。最後までお読みいただきありがとうございました。