user1801716
user1801716

Reputation: 113

Difference between these two wildcards

Are the following method declarations,

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

and

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

the same?

Upvotes: 3

Views: 118

Answers (2)

Mikhail Vladimirov
Mikhail Vladimirov

Reputation: 13890

The difference is that the former does not compile, while the latter does. Is it what you were asking?

If you meant difference between:

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

and

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

then the difference is that in first case you cannot refer to actual type of ArrayList elements, while in second case you can.

Probably, the difference will be more obvious if we will consider the following two cases:

public void testMethod (
    ArrayList <? extends Animal> l1, 
    ArrayList <? extends Animal> l2)

and

public <T extends Animal> void testMethod (
    ArrayList <T> l1, ArrayList <T> l2)

In the first case, first argument is an ArrayList of some type that extends Animal, the second argument is an Arraylist or some (probably other) type that extends Animal.

In the second case, both arguments are ArralLists of the same type that extends Animal.

Upvotes: 3

Perception
Perception

Reputation: 80603

They aren't the same in one important way. For the first case, the generic parameter will be bound to the scope of the class, and will not change over multiple invocations of the method.

In the second case, the generic parameter will depend on the arguments the method is called with, and can be different for each separate invocation.

So, given this class:

public class MyClass<T extends Animal> {
    public void handleList1(List<T> list) {
       // implementation
    }

    public <U extends Animal> void handleList2(List<U> list) {
        // implementation
    }
}

Instantiating it as:

MyClass<Bear> test = new MyClass<Bear>();

You will only be able to call handleList1 with lists of type Bear. On the other hand, you can call handleList2 as:

test.handleList2(new ArrayList<Tiger>);
test.handleList2(new ArrayList<Lion>);
test.handleList2(new ArrayList<Puma>);

Because the generic parameter for it is determined by the argument supplied too the method.

Upvotes: 4

Related Questions