5.1.10 Capture Conversionの JLS の話に気付きましたが、それらが何であるかを理解できません。
誰かが私にそれらを説明したり、例を挙げたりできますか?
5.1.10 Capture Conversionの JLS の話に気付きましたが、それらが何であるかを理解できません。
誰かが私にそれらを説明したり、例を挙げたりできますか?
Capture conversion was designed to make wildcards (in generics), ?
useful.
Suppose we have the following class:
public interface Test<T> {
public void shout(T whatever);
public T repeatPreviousShout();
}
and somewhere on our code we have,
public static void instantTest(Test<?> test) {
System.out.println(test.repeatPreviousShout());
}
Because test
is not a raw Test
and since repeatPreviousShout()
in "hindsight" returns a ?
, the compiler knows that there's a T
that serves as a type parameter for Test
.
This T
is for some unknown T
so the compiler erases the unknown type (for wildcard, it replaces with Object
)., hence repeatPreviousShout()
returns an Object
.
But if we had,
public static void instantTest2(Test<?> test) {
test.shout(test.repeatPreviousShout());
}
The compiler would give us an error of something like Test<capture#xxx of ?> cannot be applied
(where xxx
is a number, e.g. 337
).
This is because the compiler tries to do the type safety check on shout()
but since it received a wildcard, it doesn't know what T
represents, hence it creates a placeholder called capture of.
From here (Java theory and practice: Going wild with generics, Part 1), it clearly states:
Capture conversion is what allows the compiler to manufacture a placeholder type name for the captured wildcard, so that type inference can infer it to be that type.
Hope this helps you.
ワイルドカード型引数を含むパラメーター化された型は、実際には共用体型です。例えば
List<? extends Number> = Union{ List<S> | S <: Number }
2 つのケースでは、Java は を使用する代わりにList<? extends Number>
、キャプチャされたバージョン を使用しますList<S>
。ここで、S は上限 を持つ作成されたばかりの型変数ですNumber
。
(1) http://java.sun.com/docs/books/jls/third_edition/html/expressions.html
式の種類を絞り込む。式の型が である場合、オブジェクトの実行時の型が実際には具体的な型 S ( )List<? extends Number>
であることが確実にわかります。そのため、コンパイラは代わりに使用して、より正確な型分析を実行します。List<S>
S <: Number>
List<S>
キャプチャ変換は、各式に個別に適用されます。これにより、いくつかのばかげた結果が得られます。
<T> void test1(List<T> a){}
<T> void test2(List<T> a, List<T> b){}
List<?> x = ...;
test1(x); // ok
test2(x, x); // error
(2) http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.10.2
サブタイプのチェックA :< B
でA
は、ワイルドカード引数が含まれます。例えば、
List<? extends Number> :< B
<=>
Union{ List<S> | S <: Number} :< B
<=>
List<S> :< B, for all S <: Number
つまり、実際には、タイプのキャプチャされたバージョンをチェックしていますA