Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wildcard VS T - getting and adding to a list

Tags:

java

generics

Consider the following program:

public class WCVsT {

    private void fooWC(List<? extends Number> l ) {
        l.add(l.get(0)); // 1 -  A Compile time error
    }

    private <T extends Number> void fooT(List<T> l) {
        l.add(l.get(0)); // 2 - No compile time error
    }
}

I have a couple of questions regarding it:

  1. At 1 (in fooWC method) I am retrieving an element from the list and adding it back to the same list - what could be type unsafe about it? Why does the compiler not allow such operation? I can understand that the compiler doesn't allow adding a Cat to List<? extends Animal> because I could have passed dogs to fooWC but what my program shows now should always be safe. Isn't it?
  2. Why the fooT method that uses Type parameter instead of wildcard allow such an operation whereas fooWC - the wildcard version doesn't?

Any help/hint will be greatly appreciated. Thanks in advance.

like image 630
Asif Avatar asked Nov 24 '25 15:11

Asif


1 Answers

The reason one works and the other doesn't is that while both methods use the bound <T extends Number>, in the second method (the typed method), the type although unknown, is the same type throughout the method - the type is locked to a particular (but unknown) type for the duration of the call.

In the first method (the untyped one), the compiler knows only that the list of unknown is having added to it an unknown type, which is possibly a different unknown type. The fact that it's obvious to humans that it must be the same type because the target and source are the same object are invisible to the compiler.

The first version is considered by the compiler to be in the same bucket as:

List<Integer> list1;
List<Double> list2;
list1.add(list2.get(0);

It just knows that the types are both bounded by Number, but not necessarily the same type.

The second version is in the same bucket as:

List<Integer> list1;
List<Integer> list2;
list1.add(list2.get(0);

The compiler doesn't know the type, but knows it's the same type.

like image 134
Bohemian Avatar answered Nov 26 '25 03:11

Bohemian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!