Provide Best Programming Tutorials

Wildcard In Generic

A wildcard generic type has three forms

  • ?

  • ? extends T

  • ? super T ,

where T is a generic type.

Examples

unbounded wildcard example

Example shows an example of using the ? wildcard in the print method that prints

objects in a stack and empties the stack.<?> is a wildcard that represents any object type. It

is equivalent to <? extends Object> . What happens if you replace GenericStack<?>

with GenericStack<Object> ? It would be wrong to invoke print(intStack) ,

because intStack is not an instance of GenericStack<Object> . Please note that

GenericStack<Integer> is not a subtype of GenericStack<Object> , even though

Integer is a subtype of Object .

import DefineGenericClassAndInterface.GenericStack;

public class AnyWildCardDemo {

    public static void main(String[] args) {
        GenericStack<Integer> intStack = new GenericStack();
        intStack.push(1); // 1 is autoboxed into new Integer(1)
        intStack.push(2);
        intStack.push(-2);

        print(intStack);
    }

    /**
     * Prints objects and empties the stack
     */
    public static void print(GenericStack<?> stack) {
        while (!stack.isEmpty()) {
            System.out.print(stack.pop() + " ");
        }
    }
}

If we change print method to below will cause an error.

 public static void print(GenericStack<Object> stack) {
        while (!stack.isEmpty()) {
            System.out.print(stack.pop() + " ");
        }
 }
Exception in thread "main" java.lang.ClassCastException: java.base/java.lang.Integer cannot be cast to java.base/java.lang.String
    at BadExample.main(BadExample.java:14)

Process finished with exit code 1

lower-bounded wildcard example

package superwildcarddemo;

import DefineGenericClassAndInterface.GenericStack;

public class SuperWildCardDemo {
    public static void main(String[] args) {
        GenericStack<String> stack1 = new GenericStack();
        GenericStack<Object> stack2 = new GenericStack();
        stack2.push("Java");
        stack2.push(2);
        stack1.push("Sun");
        add(stack1, stack2);
    }

    public static <T> void add(GenericStack<T> stack1, GenericStack<? super T> stack2) {
        while (!stack1.isEmpty())
            stack2.push(stack1.pop());
    }

    //If we change GenericStack<? super T> to GenericStack<T> will cause an error
//    public static <T> void add(GenericStack<T> stack1, GenericStack<T> stack2) {
//        while (!stack1.isEmpty())
//            stack2.push(stack1.pop());
//    }
}

bound wildcard example

package boundWildcard;

import DefineGenericClassAndInterface.GenericStack;

public class BoundWildCardDemo {
    public static void main(String[] args) {
        GenericStack<String> stack1 = new GenericStack();
        GenericStack<Object> stack2 = new GenericStack();
        stack2.push("Java");
        stack2.push(2);
        stack1.push("Sun");
        add(stack1, stack2);
        diaplyStackElement(stack2);
    }

    public static <T> void add(GenericStack<? extends T> stack1, GenericStack<T> stack2) {
        while (!stack1.isEmpty())
            stack2.push(stack1.pop());
    }

    public static <T> void diaplyStackElement(GenericStack<T> stack) {
        while (!stack.isEmpty()) {
            System.out.println(stack.pop());
        }
    }
}

Leave a Reply

Close Menu