- 締切済み
Generics で型チェック
List<?> 型で受け取ったデータを List<A> 型か List<B> 型か判定して処理する必要があるのですが 何かお勧めの方法はあるでしょうか? obj instanceof List<A> とかくと、「ここでは List<?> を使えとコンパイラに怒られてしまいます。 List<?>では意味が無いので、現状は List の要素を取り出して判定としていますが、結構手間ですし、 実は要素が無い時や null データでも処理を切り替えなくてはなりませんので、 現在は入れるデータが無くてもダミーデータを入れてもらってしのいでます。 もっとましな方法はないでしょうか?
- みんなの回答 (2)
- 専門家の回答
みんなの回答
> Java の Generics では型パラメータはコンパイル時までしか存在せず、 > 実行時には無くなっています。 いいえケースバイケースで残りますよ。 http://ideone.com/J5FFW private List<E> list; -> E private List<String> slist; -> String
- root139
- ベストアンサー率60% (488/809)
Java の Generics では型パラメータはコンパイル時までしか存在せず、実行時には無くなっています。 したがって、型パラメータも含めた型チェックを実行時に行うことは出来ません。 obj instanceof List<?> も java.util.List で有るか否かを判定しているだけです。 詳しくは下記のページの「Erasureの意味合い」の章を見て下さい。 http://www.ibm.com/developerworks/jp/java/library/j-jtp01255/#4.0 対策としては、配列を使うか、要素クラスの java.lang.Class<T> オブジェクトも併せて受取るようにするくらいしか無いかと思います。 配列は実行時にも要素型を判定でき、また、共変でも有るので、 Object[] を受取るようにすればどんなクラスの配列でも受取れ、要素型の判断も出来ます。 例) ---------------------------------------------- public static void main(String[] args) { final List<String> list = new ArrayList<String>(); checkType(list); checkType(list.toArray(new String[list.size()])); // true checkType(list.toArray()); // false checkType(list, String.class); // true } private static void checkType(List<?> list) { System.out.println(list instanceof List<String>); // コンパイルエラー } private static void checkType(Object[] array) { System.out.println(array instanceof String[]); } private static void checkType(List<?> list, Class<?> clazz) { System.out.println(String.class.isAssignableFrom(clazz)); } --------------------------------------------------
お礼
なるほど。他の言語では簡単だったので、 Javaでも可能と思っていたのですが、 Javaではコレクションの中身がないと 本質的に実行時の型判定は不可能ということなんですね。 これを元に対策を考えてみます。