第34 回 コレクションの動的な型保証
今回のテーマは「コレクションの動的な型保証」です。
コレクションの要素に対して、コンパイル時に、つまり静的に型保証をするのは、ジェネリックスです。 しかし、実はジェネリックスのみで完全にコレクションの要素の型を保証することはできません。 以下のソースでは、要素がInteger型のListにObject型が追加されています。
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> integerList = new ArrayList<Integer>(); addObject(integerList); for (int i = 0; i < integerList.size(); i++) { System.out.println(integerList.get(i)); } } public static void addObject(List list) { list.add(new Object()); } }
ジェネリックス導入前と導入後のクラスが混じっている場合に起こりうる状況ですね。 では、完全に要素の型を保証するにはどうすればよいのでしょうか。
ここで考えられるのが、実行時、つまり動的な型保証です。 要素の追加時に、指定された型かどうかをチェックするのです。 動的な型保証には、java.util.CollectionsクラスのcheckedList,checkedMapメソッド等を使います。
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> integerList = Collections.checkedList (new ArrayList<Integer>(), Integer.class); addObject(integerList); for (int i = 0; i < integerList.size(); i++) { System.out.println(integerList.get(i)); } } public static void addObject(List list) { list.add(new Object()); } }
checkedListメソッドを使用することにより、指定した型以外の要素が追加された場合、java.lang.ClassCastExceptionが発生するようになります。
サードパーティーのクラスによってコレクションに不適切な型が混入することを防いだり、異常が発生した場合のデバッグ等に役立ってくれるでしょう。