Java でパラメタライズされたコレクションをキャストする場合
「Javaでキャストする時」や、「Javaでキャストする時」に便乗。
Java の場合、コンパイル後は型パラメータの型情報が無いので、型警告なしにキャストできないのは致し方ない。
id:Yamashiro0217 氏がやっているように、型警告の抑制を一箇所にあつめてキャストするのがベターな方法だと思うのだけど、あえて型警告の抑制を書かない方法を考えてみた。
新しいリストを作って、そこに移し替えているのでキャストではないし、実行効率もメモリ効率も悪いので、わざわざこんな方法はとらないと思うけど。
public static <T> List<T> reinterpret(final List<?> src, final Class<T> clazz) { final List<T> result = new ArrayList<T>(); for (final Object element: src) { result.add(clazz.cast(element)); } return result; }
以下は実際に使ってみた例。
import java.util.ArrayList; import java.util.List; public class ReinterpretParameterizedList { public static void main(final String[] args) { final List<Integer> src = new ArrayList<Integer>(); src.add(1); src.add(2); src.add(3); System.out.println(src); final List<? extends Number> intermediate = src; final Number first = src.get(0); System.out.println(first); // src.add(Integer.valueOf(4)); // compile error. final List<Integer> dest = reinterpret(intermediate, Integer.class); final Integer second = src.get(1); System.out.println(second); dest.add(Integer.valueOf(4)); System.out.println(dest); } public static <T> List<T> reinterpret(final List<?> src, final Class<T> clazz) { final List<T> result = new ArrayList<T>(); for (final Object element: src) { result.add(clazz.cast(element)); } return result; } }
あまり意味は無いけど、以下実行結果。
[1, 2, 3]
1
2
[1, 2, 3, 4]