The question mark (?) is known as the wildcard in generic programming. It represents an unknown type. The wildcard can be used in a variety of situations such as the type of a parameter, field, or local variable; sometimes as a return type. Unlike arrays, different instantiations of a generic type are not compatible with each other, not even explicitly. This incompatibility may be softened by the wildcard if ? is used as an actual type parameter.
Types of wildcards in Java
1. Upper Bounded Wildcards:
These wildcards can be used when you want to relax the restrictions on a variable. For example, say you want to write a method that works on List < Integer >, List < Double >, and List < Number >, you can do this using an upper bounded wildcard.
To declare an upper-bounded wildcard, use the wildcard character ('?'), followed by the extends keyword, followed by its upper bound.
public static void add(List<? extends Number> list)
Implementation:
Java
// Java program to demonstrate Upper Bounded Wildcards
import java.util.Arrays;
import java.util.List;
class WildcardDemo {
public static void main(String[] args)
{
// Upper Bounded Integer List
List<Integer> list1 = Arrays.asList(4, 5, 6, 7);
// printing the sum of elements in list
System.out.println("Total sum is:" + sum(list1));
// Double list
List<Double> list2 = Arrays.asList(4.1, 5.1, 6.1);
// printing the sum of elements in list
System.out.print("Total sum is:" + sum(list2));
}
private static double sum(List<? extends Number> list)
{
double sum = 0.0;
for (Number i : list) {
sum += i.doubleValue();
}
return sum;
}
}
OutputTotal sum is:22.0
Total sum is:15.299999999999999
Explanation:
In the above program, list1 and list2 are objects of the List class. list1 is a collection of Integer and list2 is a collection of Double. Both of them are being passed to method sum which has a wildcard that extends Number. This means that list being passed can be of any field or subclass of that field. Here, Integer and Double are subclasses of class Number.
2. Lower Bounded Wildcards:
It is expressed using the wildcard character ('?'), followed by the super keyword, followed by its lower bound: <? super A>.
Syntax: Collectiontype <? super A>
Implementation:
Java
// Java program to demonstrate Lower Bounded Wildcards
import java.util.Arrays;
import java.util.List;
class WildcardDemo {
public static void main(String[] args)
{
// Lower Bounded Integer List
List<Integer> list1 = Arrays.asList(4, 5, 6, 7);
// Integer list object is being passed
printOnlyIntegerClassorSuperClass(list1);
// Number list
List<Number> list2 = Arrays.asList(4, 5, 6, 7);
// Integer list object is being passed
printOnlyIntegerClassorSuperClass(list2);
}
public static void printOnlyIntegerClassorSuperClass(
List<? super Integer> list)
{
System.out.println(list);
}
}
Output[4, 5, 6, 7]
[4, 5, 6, 7]
Explanation:
Here arguments can be Integer or superclass of Integer(which is Number). The method printOnlyIntegerClassorSuperClass will only take Integer or its superclass objects. However, if we pass a list of types Double then we will get a compilation error. It is because only the Integer field or its superclass can be passed. Double is not the superclass of Integer.
Note: Use extend wildcard when you want to get values out of a structure and super wildcard when you put values in a structure. Don’t use wildcard when you get and put values in a structure. You can specify an upper bound for a wildcard, or you can specify a lower bound, but you cannot specify both.
3. Unbounded Wildcard:
This wildcard type is specified using the wildcard character (?), for example, List. This is called a list of unknown types. These are useful in the following cases -
- When writing a method that can be employed using functionality provided in Object class.
- When the code is using methods in the generic class that doesn't depend on the type parameter
Implementation:
Java
// Java program to demonstrate Unbounded wildcard
import java.util.Arrays;
import java.util.List;
class unboundedwildcardemo {
public static void main(String[] args)
{
// Integer List
List<Integer> list1 = Arrays.asList(1, 2, 3);
// Double list
List<Double> list2 = Arrays.asList(1.1, 2.2, 3.3);
printlist(list1);
printlist(list2);
}
private static void printlist(List<?> list)
{
System.out.println(list);
}
}
Output[1, 2, 3]
[1.1, 2.2, 3.3]
Similar Reads
Recursion in Java
In Java, Recursion is a process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. Using a recursive algorithm, certain problems can be solved quite easily. A few Java recursion examples are Towers of Hanoi (TOH)
6 min read
JRE in Java
Java Runtime Environment (JRE) is an open-access software distribution that has a Java class library, specific tools, and a separate JVM. In Java, JRE is one of the interrelated components in the Java Development Kit (JDK). It is the most common environment available on devices for running Java prog
4 min read
JDK in Java
The Java Development Kit (JDK) is a cross-platformed software development environment that offers a collection of tools and libraries necessary for developing Java-based software applications and applets. It is a core package used in Java, along with the JVM (Java Virtual Machine) and the JRE (Java
5 min read
Super Keyword in Java
The super keyword in Java is a reference variable that is used to refer to the parent class when we are working with objects. You need to know the basics of Inheritance and Polymorphism to understand the Java super keyword. The Keyword "super" came into the picture with the concept of Inheritance. I
7 min read
Separators in Java
Be it a programmer who is unaware of this concept but is indulging in every program. Separators help us defining the structure of a program. In Java, There are few characters used as separators. The most commonly used separator in java is a semicolon(;). Let us explore more with the help of an illus
2 min read
Java Keywords
In Java, keywords are the reserved words that have some predefined meanings and are used by the Java compiler for some internal process or represent some predefined actions. These words cannot be used as identifiers such as variable names, method names, class names, or object names. Now, let us go t
5 min read
Stream In Java
Stream was introduced in Java 8, the Stream API is used to process collections of objects. A stream in Java is a sequence of objects that supports various methods that can be pipelined to produce the desired result. Use of Stream in JavaThe uses of Stream in Java are mentioned below:Stream API is a
7 min read
Native Keyword in Java
The native keyword in Java is applied to a method to indicate that the method is implemented in native code using JNI (Java Native Interface). The native keyword is a modifier that is applicable only for methods, and we canât apply it anywhere else. The methods which are implemented in C, C++ are ca
4 min read
Shift Operator in Java
Operators in Java are used to performing operations on variables and values. Examples of operators: +, -, *, /, >>, <<. Types of operators: Arithmetic Operator,Shift Operator,Relational Operator,Bitwise Operator,Logical Operator,Ternary Operator andAssignment Operator. In this article, w
4 min read
Important Keywords in Java
Keywords refer to the reserved set of words of a language. These are used for some predefined actions. abstract: It is a non-access modifier applicable for classes and methods. It is used to achieve abstraction. For more, refer to abstract keyword in javaenum: It is used to define enum in Javainstan
2 min read