arc
arc

Reputation: 113

Instantiation of Generic object with wildcard

I have a class

public class OrderedBox<T> {}    


Compiler doesn't allow to create member/local variable like these.

OrderedBox<? extends T> testItems1 = new OrderedBox<? extends T>();
List<? extends T> testItems2 = new ArrayList<? extends T>();

Its understandable cause at runtime, it doesn't guarantee the type of objects (upper bounded by T) will be inserted and will defy the typesafety.

But it allows to create member/local variable like these. Why and How does it allow this ?

private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>();



Note: I have this doubt while going through http://www.onjava.com/pub/a/onjava/excerpt/javaian5_chap04/index1.html

Probable duplicates :
Creating new generic object with wildcard
Generics wildcard instantiation

But both of these questions provides the reasoning for the compilation failure of the 2 options. I couldn't understand why and how the last 1 is allowed.

Upvotes: 3

Views: 934

Answers (2)

Naresh Joshi
Naresh Joshi

Reputation: 4587

Your list object is bag a where you can keep many OrderedBox objects

private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>();

It doesn't matter what that OrderedBox have in it at compile time, using this kind of syntax will cause you problems when you try to insert objects into that list.

You should use generics (wildcard) while declaring a class, But While creating objects for that class you should be specific like

private List<OrderedBox<Object>> testItems = new ArrayList<OrderedBox<Object>>();

Compiler will not allow

OrderedBox<? extends T> testItems1 = new OrderedBox<? extends T>();

because here you are not telling, what is the type of OrderedBox, you should be specific here as well.

Upvotes: 0

Simon
Simon

Reputation: 2433

The answer for the one line variation is actually explained in the second SO question you posted: Generics wildcard instantiation

The One-liner does declare a type of OrderedBox but does not create an instance of it.

private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>();

This says that you will have an OrderedBox but it does not say which one. You will have troubles when trying to create an instance like

testItems.add(new OrderedBox<? extends T>())

Because at that time, you will fix the type.

Upvotes: 5

Related Questions