The Get & the Put Principle
This lesson provides examples on the get and the put principle to be followed when working with generics.
We'll cover the following...
What is the Get and Put principle?
Consider the code snippet below. This time we are saving a Number into a list of types that extends Number. Will this work?
void addNumber(Number num) {
List<? extends Number> listOfNumbers = new ArrayList<>();
listOfNumbers.add(num); // Will this work?
}
Compiles
Doesn’t compile
Compiles with a checked warning and throws a runtime ClassCastException
The above code will never compile because we are trying to add a number into a list of a type that extends Number and we can't guarantee the type of the number being passed into the method. Actually, the way the code is written, it is pretty useless. The list can never be added to since it is being declared inside the method and new-ed up at the same time.
Usually, list with unbounded wildcard or an extends wildcard bound are used to declare the parameter types in the method signature and not as variables inside a method.
Note that List<? extends Number>
does not mean list of objects of different types, all of which extend Number. Rather it implies list of objects of a single type which extends Number.
Can we consider List<?>
as an immutable list since we can never add to this list?
import java.util.*;class Demonstration {public static void main( String args[] ) {List<? super Number> listOfNumbers = new ArrayList<>();Integer i = Integer.valueOf(5);Double d = Double.valueOf(5);// Adding an integerlistOfNumbers.add(i); // Allowed// Adding a doublelistOfNumbers.add(d); // Allowed// i = listOfNumbers.get(0); // <--- Compile time errorObject object = listOfNumbers.get(0); // Allowed}}
What to do when we want to both get and put values in a structure?