項目 24: 無検査警告を取り除く
型パラメータを書いていないなどの理由で、コンパイル時に無検査警告が出ることがある。 無検査警告は全て取り除くべきである。 なぜなら、全ての警告を取り除けば、そのコードは型安全であると保証できるからである。
もし、警告を取り除くことができなくても、そのコードが型安全であると確かに示せるならば、
@SuppressWarnings("unchecked")
というアノテーションにより、警告を抑制することができる。 このアノテーションは、できるだけ小さいスコープに対して用いるべきである(一つの変数宣言など)。 また、警告を抑制するときは、他者が理解しやすいように、コメントに理由を書くべきである。
項目 25: 配列よりリストを選ぶ
ジェネリックな配列は作れないという話。 まずイレイジャについて説明したあと、なぜジェネリックな配列が作れないか説明する。
イレイジャ
イレイジャはジェネリックスを実現するための機構である。 型パラメータを持つ宣言は、コンパイル時にイレイジャによって型パラメータの情報が消される。 例えば、以下のコードを考える。
List<Integer> list= new ArrayList<Integer>();
このコードは、実行時は以下のコードと見なされる。
List list = new ArrayList();
イレイジャで実行時は型情報を破棄することで、ジェネリックスを使っていない過去のコードと相互運用できるようにしてある。
なぜジェネリックな配列は作れないか
以下のコードの 1 行目にあるような、ジェネリックな配列は作れない。
List<String>[] stringListss = new List<String>[1]; // ここでコンパイルエラー List<Integer> intList = Arrays.asList(42); Object[] objects = stringLists; objects[0] = intList; String s = stringLists[0].get(0);
このコードがコンパイルできるとする。 このとき、実行時のコードは以下の通りとなる。
List[] stringListss = new List[1]; List intList = Arrays.asList(42); Object[] objects = stringLists; objects[0] = intList; String s = stringLists[0].get(0);
1, 2 行目では、イレイジャによって、型パラメータの情報が消されている。
また、3 行目で配列の共変性により stringLists
が objects
に代入されている。
これより、4 行目において、Integer
型の要素からなるリストが String
型の要素からなるリストに代入されてしまっている。
こうなると、5 行目で Integer
から String
への誤ったキャストが起こり、ClassCastException
が投げられる。
以上の処理が起きるのを防ぐために、 ジェネリック配列はコンパイルエラーとなる。
結論
以上のようなことがあるので、ジェネリックスを使いたいときは、List
などのコレクション型を利用する方がよい。
参考文献
EFFECTIVE JAVA 第2版 (The Java Series)
- 作者: Joshua Bloch,柴田芳樹
- 出版社/メーカー: 丸善出版
- 発売日: 2014/03/11
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (12件) を見る