Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
129 views
in Technique[技术] by (71.8m points)

When to use wildcards in Java Generics?

this is from HeadFirst Java: ( page 575 )

This:

public <T extends Animal> void takeThing(ArrayList<T> list)

Does the same thing as this:

public void takeThing(ArrayList<? extends Animal> list)

So here is my question: if they are exactly same, why don't we write

public <? extends Animal> void takeThing(ArrayList<?> list)

or

public void takeThing(ArrayList<T extends Animal> list)

Also, when would it be useful to use a ? instead of a T in a method declaration ( as above ) with Generics, or for a Class declaration? What are the benefits?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The big difference between

public <T extends Animal> void takeThing(ArrayList<T> list)

and

public void takeThing(ArrayList<? extends Animal> list)

is that in the former method you can refer to "T" within the method as the concrete class that was given. In the second method you cannot do this.

Here a more complex example to illustrate this:

// here i can return the concrete type that was passed in
public <T extends Animal> Map<T, String> getNamesMap(ArrayList<T> list) {
    Map<T, String> names = new HashMap<T, String>();
    for (T animal : list) {
        names.put(animal, animal.getName()); // I assume there is a getName() method
    }
    return names;
}

// here i have to use general Animal
public Map<Animal, String> getNamesMap(ArrayList<? extends Animal> list) {
    Map<Animal, String> names = new HashMap<Animal, String>();
    for (Animal animal : list) {
        names.put(animal, animal.getName()); // I assume there is a getName() method
    }
    return names;
}

With the first method if you pass in an List of Cats you get a Map with Cat as key. The second method would always return a Map with general Animal key.

By the way this is not valid java syntax:

public <? extends Animal> void takeThing(ArrayList<?> list)

Using this form of generic method declaration you have to use a valid java identifier and not "?".

Edit:

The form "? extends Type" only applies to variable or parameter type declaration. Within a generic method declration it has to be "Identifier extends Type" as you are able to refer to the "Identifier" from within your method.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...