Wildcard Capture

Java-Wildcard Capture

Wildcard Capture 

Generic methods can do one more trick for us involving taming wildcard instantiations of generic types. The term wildcard capture refers to the fact that generic methods can work with arguments whose type is a wildcard instantiation of a type, just as if the type were known. For example, consider the following classes, generic method and statements :

Wildcard Capture

The result of these examples is that we converted an unknown instantiation of Genone to an unknown instantiation of GenTwo. The generic method type variable  V represents the actual type of the argument, g1, for purposes of the method body. The wildcard instantiation must match any bounds of the method type variable. For example:

Wildcard Capture

But because we can work with the type variable only through its bounds types, the compiler is free to refer to it by this new name, V, as if it were a known type. That may not seem very interesting, but it is useful because it allows methods that accept wildcard instantiations of types to delegate their work to other generic methods.

Another way to look at this is that generic methods are a more powerful alternative to methods using wildcard instantiations of types. Trying to work with an object through a wildcard instantiation of its generic type limits us to “reading” the object. We cannot “write” types to the object because its parameter type is unknown. In contrast, because generic methods can infer or “capture” an actual type for their arguments, they allow us to do a lot more with broad ranges of types than we could with wildcard instantiations alone.

For example, suppose we wanted to write a utility method that swaps the elements of a specified object. Using wildcards, we would like to write something like following:

Wildcard Capture

But we are not allowed to call the setT1() and setT2() methods of our object because we don’t know what type it actually holds. We are really stuck and there isn’t much we can do. But the corresponding generic method gives us a real type to done this job. For example:

Wildcard Capture

Here, we are able to declare a variable of the correct (inferred) type and write using the setT1() and setT2() methods appropriately. It would seem that generic methods are the only way to go here.

Program

Wildcard Capture


Program Source

class GenOne<T> {
    
    private T t1;
    private T t2;
    
    void setT1(T t){ t1 = t; }
    void setT2(T t){ t2 = t; }
    
    T getT1(){ return t1; }
    T getT2(){ return t2; }
}

public class Javaapp {
    
    static <V> void swap(GenOne<V> g1){
        
        V getT1 = g1.getT1();
        g1.setT1(g1.getT2());
        g1.setT2(getT1);
    }
    
    public static void main(String[] args) {
        
        GenOne<Integer> g1 = new GenOne<Integer>();
        g1.setT1(50);
        g1.setT2(100);
        System.out.println("Before Swapping : "+g1.getT1()+","+g1.getT2());
 
        GenOne<?> anyg1 = g1;
        swap(anyg1);
        System.out.println("After Swapping : "+g1.getT1()+","+g1.getT2());
    }
}

Leave a Comment