今回はちょっとしたJavaのクイズをお出ししましょう。
List<String> listA = new ArrayList<String>();
List<Object> listB = listA;
というコードを書いたとき、listB = listAの代入はコンパイルエラーとなります。
さて、なぜでしょう?
それでは、次のようなコードを実行するとどうなるでしょうか?
List<String> listA = new ArrayList<String>();
List<Object> listB = listA;
listB.add(new Object());
listAの参照するオブジェクトとlistBの参照するオブジェクトは同じなのですが…。おやおや?
listBにaddすると、listAも同じものですからArrayListにObjectがaddされることになりますね。
このようなことが起こってしまうのでジェネリクスのパラメータ型が継承関係(今の場合String extends Objectですね)
にあっても代入することはできないのです。
しかし、次のような記述にするとコンパイルすることが出来ます。
List<String> listA = new ArrayList<String>();
List<? extends Object> listB = listA;
ところが、
listB.add(new Object());
とするとコンパイルエラーになるのです。
<? extends ~>型のジェネリクスを使うと、値の取得は出来ても値を設定することはできないのです。
こうして型の互換性のないオブジェクトの混入を防いでいるのですね。
投稿日時 : 2007年8月3日 23:34