Wildcard in Java – Important Concept of Java Generics

Moving ahead in our Java journey, in this article, we will discuss Wildcard In Java. A wildcard in Java is a useful concept in Java Generics. We will learn what is a wildcard in Java and how can we incorporate it into our Java programs.

There are 3 types of wildcards in Java: Upper bounded wildcards, Lower Bounded Wildcards, and Unbounded Wildcards. We will discuss each of them with an example. So, let’s start learning wildcards in Java.

What is Wildcard in Java?

 

Wildcards in Java are basically the question marks which we use in generic programming, it basically represents the unknown type. We use Java Wildcard  widely in situations such as in a type of parameter, local variable, or field and also as a return type.

Unlike arrays, different instantiations of a generic type are not compatible with each other, not even explicitly. We can remove this incompatibility by using wildcard ‘?’ as an actual type parameter.

Wildcards are nothing but the question mark(?) that you use in the Java Generics. We can use the Java Wildcard as a local variable, parameter, field or as a return type. But, when the generic class is instantiated or when a generic method is called, we can’t use wildcards.

The wildcard is useful to remove the incompatibility between different instantiations of a generic type. This incompatibility is removed by using wildcards ? as an actual type parameter.

There are two types of parameters that we pass to a method in the form of in and out parameters. They are:

1. in variable

in variable is a variable that provides the actual data to the Java program. For example, there is a method myMethod(source, destination). In this method, the source acts as an in variable to the method.

2. out variable

out variable is a variable in which the updated data gets stored by the java program. For example, there is a method myMethod(source, destination). In this method, destination acts as an out variable to the method.

Types of Wildcard in Java

1. Upper Bounded Wildcards
2. Lower Bounded Wildcards
3. Unbounded Wildcards

1. Upper Bounded Wildcards

The Upper Bounded wildcards are the wildcard that relaxes the restriction of the variable type. That is, if we want to relax the restriction on the type of the variable in the method, we can use this type of wildcards.

For example, we are using the upper bound wildcard in the method sum that calculates the sum of any type of variable whether it is int or a double type variable. This example is shown in the following Java code:

public class UpperBoundWildcard {
  public static void main(String[] args) {
    //Upper Bounded Integer List 
    List < Integer > intList = Arrays.asList(10, 20, 30, 40);

    //printing the sum of integer elements in list 
    System.out.println("Total sum is:" + sum(intList));

    //Upper Bounded Double list 
    List < Double > doubleList = Arrays.asList(13.2, 15.6, 9.7, 22.5);

    //printing the sum of double elements in list 
    System.out.print("Total sum is: " + sum(doubleList));
  }
  private static double sum(List < ?extends Number > myList) {
    double sum = 0.0;
    for (Number iterator: myList) {
      sum = sum + iterator.doubleValue();
    }
    return sum;
  }
}

Output
Total sum is: 100.0
Total sum is: 61.0

2. Lower Bounded Wildcards

We use the Lower Bounded wildcards to widen the use of the type of variable. For example, if we want to add the list of integers in our method we can use the List<Integer>, but using this we will be bound to use only the list of integers.

So here, we can also use the List<Number> and List<Object> to store the list of integers. So we use the Lower Bounded wildcard to achieve this. We can use this by a wildcard character ? and put a super keyword after that followed by the lower bound.
Example: <? super LowerBound>

package com.techvidvan.wildcards;
import java.util. * ;
public class LowerBoundWildcard {
  public static void main(String[] args) {
    //Lower Bounded Integer List 
    List < Integer > intList = Arrays.asList(10, 20, 30, 40);

    //Passing Integer list object 
    printOnlyIntegerClassorSuperClass(intList);

    //Number list 
    List < Number > numberList = Arrays.asList(10, 20, 30, 40);

    //Passing Integer list object 
    printOnlyIntegerClassorSuperClass(numberList);
  }

  public static void printOnlyIntegerClassorSuperClass(List < ?super Integer > list) {
    System.out.println(list);
  }
}

Output:
[10, 20, 30, 40]
[10, 20, 30, 40]

3. Unbounded Wildcards

We use the Unbounded wildcards when we want to specify the type of wildcard with the wildcard character ?.  We generally use this wildcard when the code inside the method is using the Object functionality and also when the code inside the method does not depend upon the parameter type.

package com.techvidvan.wildcards;
import java.util. * ;
public class UnboundedWildcard {
  public static void main(String[] args) {
    //Integer List 
    List < Integer > intList = Arrays.asList(10, 20, 30, 40);

    //Double list 
    List < Double > doubleList = Arrays.asList(11.5, 13.6, 67.8, 43.7);

    printList(intList);
    printList(doubleList);
  }
  private static void printList(List < ?>list) {
    System.out.println(list);
  }
}

Output:
[10, 20, 30, 40]
[11.5, 13.6, 67.8, 43.7]

So if we briefly wrap up about each wildcard, we can say their usage in the following three ways:

  • Upper bound Wildcard: ? extends Type.
  • Lower bound Wildcard: ? super Type.
  • Unbounded Wildcard: ?

Guidelines for Using Wildcard in Java

Below is the guideline for using each type of variable in the following cases:

  • Upper bound wildcard: If the variable belongs to in type , i.e there is an in variable, we use the ‘extends’ keyword with a wildcard.
  • Lower bound wildcard: If the variable belongs to out type , i.e there is an out variable, we use ‘super’ keyword with a wildcard.
  • Unbounded wildcard: If we can access a variable using the Object class method, then we should prefer to use the unbounded wildcards.
  • No wildcard: If the variable is both in and out category, then there is no need to use the wildcards.

Conclusion

In this article, we studied the wildcard in java. We use wildcard in Java while using generics in Java. We studied how we can use them according to our needs. Wildcards help us in providing the facility of passing the actual parameter type.

There are three types of wildcards in Java which are Upper Bounded wildcards, Lower Bounded, and Unbounded wildcards. We discussed each of them with examples. We hope this article will help you in building your concepts on Wildcards in Java.