I've noticed JLS talks of 5.1.10 Capture Conversion, but I fail to understand what they are.
Can anyone explain them to me/give examples?
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.