Monday, January 20, 2020

Generic wildcards

Generic wildcards

In generics, ? (question mark) represents wildcard, means unknown type. Wildcard can be applied in different situations as the parameter, field, or local variable, or even as  a return type to a method. We can't use wildcards as type argument for a generic method invocation, a generic class instance creation, or a super type.

There can be three types of Generic wildcards
  1. Upper bound wildcards
  2. Unbounded wildcards
  3. Lower wild cards
Upper Bound Wildcards

We can reduce/relax  the restrictions on a variable using upper bound wildcards. We use keyword extends like <? extends MyClass> to apply Upper bound wildcards. 

Example:
'
Upper bounded wildcards
/**********************************************************************/
class GenRectangle<T>
{
    T h;
    T w;
    public GenRectangle(T h, T w) {
        super();
        this.h = h;
        this.w = w;
    }
   
}
class Utilnew
{
    public static <T> void getArea(GenRectangle<? extends Number> r)//upper bound wildcard
    {
        System.out.println("Area:" + r.h.floatValue() * r.w.floatValue());
    }
}
public class WildcardDemo {

    public static void main(String[] args) {
        GenRectangle<Float> g=new GenRectangle(12.3f, 15.7f);
        Utilnew.getArea(g);
    }

}

Unbound Wildcards

When, we are not relaxing or applying any restriction over the type, then we can simply use unbounded wildcards.

Example:


Unbounded wildcards
/***********************************************************/

class GenRectangle<T>//generic type
{
    T h,w;
    public GenRectangle(T h, T w) {//generic constructor
        super();
        this.h = h;
        this.w = w;
    }
   
}
class Utilnew
{//generic method
    public static <T> void getDimensions(GenRectangle<?> r)//unbounded wildcard
    {
        System.out.println("Rectangle h :" + r.h+ " Rectangle w :"+r.w);
    }
}
public class WildcardDemo {
    public static void main(String[] args) {
        GenRectangle<Float> g=new GenRectangle(12.3f, 15.7f);
        Utilnew.getDimensions(g);
    }


}


Lower Bound Wildcards

Lower bounded wildcard restricts the unknown type to be a specific type or a super type of that type. We can use <? super MyClass> to apply lower bound wildcards. We can apply either upper bound on a wildcard or a lower bound. we can not apply both of them together.

Example:

Lower bounded wild cards
/*******************************************************************************/
class GenRectangle<T>//generic type
{
    T h,w;
    public GenRectangle(T h, T w) {//generic constructor
        super();
        this.h = h;
        this.w = w;
    }
   
}
class Utilnew
{//generic method
    public static <T> void getDimensions(GenRectangle<? super T> r)//unbounded wildcard
    {
        System.out.println("Rectangle h :" + r.h+ " Rectangle w :"+r.w);
    }
}
public class WildcardDemo {
    public static void main(String[] args) {
        GenRectangle<Float> g=new GenRectangle(12.3f, 15.7f);
        Utilnew.<Float>getDimensions(g);
    }
}

/**********************************************************************/

Video Tutorial: