List <interfaceI> vs List <? extends InterfaceI> in java

Arraylist with List<interfaceI> and List<? extends InterfaceI> List<? extends InterfaceI> both will have class objects that implement interfaceI. Then, when should I use it?

+6
source share
3 answers

Suppose Foo and Bar are two classes that implement InterfaceI .

The second ( List<? extends InterfaceI> ) does not allow adding anything to the list (except null), because the type that contains the list is unknown: it can be List<Foo> or List<Bar> : you just don’t know.

So you usually use this notation for the argument when you want the method to read the elements of the list passed as the argument, and want the calling caller to call your method using List<InterfaceI> , a List<Foo> or List<Bar> . Using List<InterfaceI> as an argument will only accept lists of type List<InterfaceI> .

Take a concrete example: you want to calculate the maximum double value of a list of numbers. This method does not need to add or install anything to the list. All he does is iterate over the elements, get each number and calculate their maximum. Signature may be

  public double max(List<Number> list); 

But then you cannot do

 List<Integer> ints = new ArrayList<>(); max(ints); 

The only way to call this method is to do

 List<Number> ints = new ArrayList<>(); max(ints); 

If you declare a method as

 public double max(List<? extends Number> list); 

then you can do

 List<Integer> ints = new ArrayList<>(); List<Long> longs = new ArrayList<>(); max(ints); max(longs) 
+9
source

The difference is that if you declare your list as List<? extends S> myList List<? extends S> myList , the variable myList can list any type that extends S , associations will work, as shown below:

 public class Clazz implements S{} List<? extends S> myList = new List<Clazz>(); // its fine as Clazz extends S List<? extends S> myList = new List<S>(); // its fine as well List<? extends S> myList = new List<Object>(); // ooooops it wil not work 

But in this case, you will not enter into the PUT anything in such a list, since you cannot guarantee the exact type of object that is held by the implementation of the list assigned by myList

If you declare a List<S> myList , than you can PUT and GET objects from the list, since you are sure that it is in it, however, assignments from above will not work!

 public class Clazz implements S{} List<S> myList = new List<Clazz>(); // no way! List<S> myList = new List<S>(); //thats perfectly fine! - You can PUT new S in it; List<S> myList = new List<Object>(); //known result; 
+1
source

here instead

 public double max(List<? extends Number> list){ 

if you like -

 public List myList(List<? extends String> list){ list.add("string");// No, can not add anything in list except null list.add(null); } 
0
source

Source: https://habr.com/ru/post/973970/


All Articles