I've read a few topics which cover certain questions about generics, such as their relationship with raw types. But I'd like an additional explanation on a certain line found in the Java SE tutorial on unbound generics .
According to a sentence :
The goal of printList is to print a list of any type, but it fails to achieve that goal — it prints only a list of Object instances; it cannot print List<Integer>, List<String>, List<Double>, and so on, because they are not subtypes of List<Object>.
If I understand well this sentence; the difference between List<?>
and List<Object>
, is that we can use the type argument List<String>
or List<Integer>
by implementing the former. While if we implement the later, we can only use the type argument List<Object>
. As if List<?>
is an upper bound to Object
namely List<? extends Object>
.
But then the following sentence confuses me, in the sense that according to what I previously understood, List<Object>
should only contain instances of the class Object
and not something else.
It's important to note that
List<Object>
andList<?>
are not the same. You can insert an Object, or any subtype of Object, into aList<Object>
. But you can only insertnull
into aList<?>
.
Unbounded wildcards An unbounded wildcard is the one which enables the usage of all the subtypes of an unknown type i.e. any type (Object) is accepted as typed-parameter. For example, if want to accept an ArrayList of object type as a parameter, you just need to declare an unbounded wildcard.
both bounded and unbounded wildcards provide a lot of flexibility on API design especially because Generics is not covariant and List<String> can not be used in place of List<Object>. Bounded wildcards allow you to write methods that can operate on Collection of Type as well as Collection of Type subclasses.
There are two scenarios where an unbounded wildcard is a useful approach: If you are writing a method that can be implemented using functionality provided in the Object class. When the code is using methods in the generic class that don't depend on the type parameter.
A bounded wildcard is one with either an upper or a lower inheritance constraint. The bound of a wildcard can be either a class type, interface type, array type, or type variable. Upper bounds are expressed using the extends keyword and lower bounds using the super keyword.
This is called a list of unknown type. There are two scenarios where an unbounded wildcard is a useful approach: If you are writing a method that can be implemented using functionality provided in the Object class. When the code is using methods in the generic class that don't depend on the type parameter.
Local field. The only restriction on wilds cards is that you cannot it as a type argument of a generic method while invoking it. Java provides 3 types of wild cards namely upper-bounded, lower-bounded, un-bounded.
Instead of the typed parameter in generics (T) you can also use “?”, representing an unknown type. You can use a wild card as a − Type of parameter. Local field. The only restriction on wilds cards is that you cannot it as a type argument of a generic method while invoking it.
It's called a wildcard type for obvious reasons. We can write: and now, we can call it with any type of collection. Notice that inside printCollection (), we can still read elements from c and give them type Object.
There are two separate issues here. A List<Object>
can in fact take any object as you say. A List<Number>
can take at least Number
objects, or of course any subclasses, like Integer
.
However a method like this:
public void print(List<Number> list);
will actually only take a List
which is exactly List<Number>
. It will not take any list which is declared List<Integer>
.
So the difference is List<?>
will take any List with whatever declaration, but List<Object>
will only take something that was declared as List<Object>
, nothing else.
The last quote simply states, that List<?>
is a list for which you literally don't know what type its items are. Because of that, you can not add anything to it other than null
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With