Java Generics Wildcard

I have a question about using wildcards in Java types: what is the main difference between List<? extends Set> List<? extends Set> and List<T extends Set> ? When will I use either?

+7
source share
5 answers

Two reasons:

To avoid unnecessary broadcasts:

You should use option T for such cases:

 public <T extends Set> T firstOf(List<T> l) { return l.get(0); } 

C this will become the following:

 public Set firstOf2(List<? extends Set> l) { return l.get(0); } 

... which does not give the same amount of information to the caller of the firstOf method. The first version allows the caller to:

 SubSet first = firstOf(listOfSubSet); 

and in the second version, you are forced to use a cast to compile it:

 SubSet first = (SubSet)firstOf(listOfSubSet); 

To apply the appropriate argument types:

 public <T extends Set> boolean compareSets(List<T> a, List<T> b) { boolean same = true; for(T at : a) { for (T bt: b) { same &= at.equals(bt); } } return same; } 

There is no direct equivalent for this using ? instead of T . Note that due to the separate sending of Java in the above version, the compiler will call the at equals(T) method, which can be very different from the at equals(Set) or equals(Object) method.

+8
source

The difference here is that in the second version, you have a variable of type T , which refers to a specific subtype of Set that contains List . You need this in cases where you need to make sure that something else is the same type as the type contained in the list. A few simple examples:

 // want to ensure that the method returns the same type contained in the list public <T extends Set> T something(List<T> list) { ... } // want to ensure both lists contain the exact same type public <T extends Set> List<T> somethingElse(List<T> first, List<T> second) { ... } 

Simple rule: Use a variable of type T extends Foo in your method signature if the same type is needed in two places. Method parameters are one place, and the type of the returned method is another. Use a wildcard ? extends Foo ? extends Foo if you just need to make sure that you are dealing with "something that is Foo " in one place.

In addition: do not use the raw type Set .

+1
source

Are you using List<? extends Set> List<? extends Set> when declaring varlable. For example:

 List<? extends Number> l = new ArrayList<Integer>(); 

List<T extends Number> can be used in the declaration of a class or method. This will allow you to later write T instead of <? extends Number> <? extends Number> to the function.

 public <T extends Number> int addAll(List<T> list) { int result = 0; for (T t : list) { result += t.intValue(); } return result; } 
0
source

We use wildcards to indicate that the type element matches anything. ? denotes an unknown type.

List<? extends Set> List<? extends Set> is an example of a restricted wildcard and indicates that a list can accept any subtype of Set (e.g. HashSet ) List<T extends Set> , on the other hand, allows T be a restricted type that extends Set .

I use wildcards when I need a dataset, regardless of its exact type.

0
source

Wildcard type G<? extends A> G<? extends A> is the supertype of any G<Ai> , where Ai is a subtype of A

In other words, G<? extends A> G<? extends A> is the union type G<A0>, ..., G<An> .

-one
source

All Articles