What is a capture conversion in Java and can anyone give me 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.

Leave a Comment