Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics, Unbound wildcards <?> vs <Object>

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> and List<?> are not the same. You can insert an Object, or any subtype of Object, into a List<Object>. But you can only insert null into a List<?>.

like image 857
Imad Avatar asked Feb 08 '16 15:02

Imad


People also ask

What are unbounded wildcards in generics Java?

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.

What is the difference between bounded and unbounded wildcards in Java generics?

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.

In which situations would you use unbounded wildcards?

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.

Is <?> A bounded wildcard?

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.

What is an unbounded wildcard in Java?

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.

What are the types of wild cards in Java?

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.

Can you use a wild card as a parameter in generics?

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.

Why is it called a wildcard type?

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.


1 Answers

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.

like image 59
Robert Bräutigam Avatar answered Sep 22 '22 19:09

Robert Bräutigam