fieldにfieldが代入できないぜぇ ワイルドカードだろ〜?
概要
wild.field に wild.fieldが代入できなくなる
やり方
- 型変数TをもつクラスCを用意します。
- CはT型のフィールドfieldをもちます。
- C<?>型の変数wildを用意すると、wild.fieldにはwild.fieldが代入できません
package test; public class CaptureConversionTest { static class C<T> { T field; } public static void main(final String[] args) { C<String> str = new C<String>(); str.field = str.field; C<?> wild = str; // コンパイルエラー // wild.field = wild.field; // ヘルパメソッドに渡せばOK assignmentAux(wild); } private static <T> void assignmentAux(final C<T> something) { something.field = something.field; } }
代入できない理由
2つのフィールド参照の式 (wild.field) でそれぞれ別々に捕捉変換 (capture conversion) が起こり、互換性のない型になるため。
Eclipseだとこんなエラーが出る。
2回目の捕捉変換でできた型から1回目の捕捉変換でできた型に変換できない ということ。
Type mismatch: cannot convert from capture#2-of ? to capture#1-of ?
[javac] C:\work\java\src\test\CaptureConversionTest.java:15: エラー: 互換性のない型 [javac] wild.field = wild.field; [javac] ^ [javac] 期待値: CAP#2 [javac] 検出値: CAP#1 [javac] CAP#1,CAP#2が新しい型変数の場合: [javac] ?のキャプチャからのCAP#1 extends Object [javac] ?のキャプチャからのCAP#2 extends Object [javac] エラー1個
あれ?右辺の方が先に捕捉変換されている?