Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use generics wildcard in List declaration?

Consider the following codes:

class Super {}
class Sub extends Super {}
class Test {
    public static void main(String[] args) {
        List<? extends Super> list = new ArrayList<Sub>(); //1
        list.add(new Sub()); //2
    }
}

Line 1 compiles successfully, but line 2 fails compilation:

The method add(capture#2-of ? extends Super) in the type List<capture#2-of ? extends Super> is not applicable for the arguments (Sub)

My questions are:
1) Why does line 1 successfully compile?
2) Is line 1 a good practice in declaring a List (or other collections)?
3) Why does line 2 fail compilation, after list was declared to be type Sub in line 1?
4) Eclipse's autocompletion says only "null" elements are allowed in list now. Why?

Thanks a lot!

like image 284
Chang Avatar asked Dec 20 '22 18:12

Chang


1 Answers

1) Why does line 1 successfully compile?

The first line compiles because List<Sub> is subclass of List<? extends Super> and that can only be true if List does not allow you to add any new members to it.

? means that you don't exactly know that it is a List<Sub> or List<Sub1>, so it is unsafe to allow adding of new elements into the list and so it does not allow it.

2) Is line 1 a good practice in declaring a List (or other collections)?

If you already know that it is going to be List<Sub> then I don't find any use, but wildcards are used much when you are passing the List around to other classes like Utilities.

3) Why does line 2 fail compilation, after list was declared to be type Sub in line 1?

Because as I already explained it is unsafe to add any element to list when you dont know the exact type.

4) Eclipse's autocompletion says only "null" elements are allowed in list now. Why?

Because null is of every reference type, this is why you can assign any object a value of null.

Always remember PECS (Producer Extends Consumer Super) rule by Josh Bloch when working with generics

Good References:

  • Difference between ? extends and ? super
  • When do we require <? extends T> as compared to <T>
like image 135
Narendra Pathai Avatar answered Dec 22 '22 07:12

Narendra Pathai