Java Generics — Assigning a list of subclass to a list of superclass

前端 未结 7 2091
我寻月下人不归
我寻月下人不归 2020-12-07 02:00

I have a basic question regarding assignment of a list of subclass to a list of superclass.

So I have something like the following:

Class B extends          


        
相关标签:
7条回答
  • 2020-12-07 02:40

    To explain this, let me substitute "B" with Integer and "A" with Number. This is just to make it a little easier to explain.

    Class Integer extends Number;
    
    List <Integer> iList = new ArrayList<Integer>();
    List <Number> nList = iList // will fail
    

    The reason this would fail is because nList can take any Number -- it can take Integer, it can take Double, or for that matter any subclass of Number. However, this is not true for iList. You cannot add a Double to iList because it accepts only Integer and its subclasses. Hope this helps explain it to you.

    0 讨论(0)
  • 2020-12-07 02:40

    Because generics are strict type safe.

    You can have

    List<? extends A> aList = bList;
    

    It says aList can hold list of any type which is an A

    0 讨论(0)
  • 2020-12-07 02:46

    Because List<B> does not extend List<A>. For example, Integer extends Number and so does Long. So List<Number> can contain both Integer and Long. So if you assign List<Integer> to List<Number> you will be able to add Long to your list of integers.

    You can declare

    List<? super B> superB;
    

    And that would allow assignment to superB of any list that contains B and its super classes. But it's not the same as in your case aList=bList.

    or

    List<? extends A> extendsA;
    

    Examples

        List<? super Integer> superA;
        superA = new ArrayList<Number>();
    
        List<? extends Number> extendsNumber;
        extendsNumber = new ArrayList<Integer>();
    
    0 讨论(0)
  • 2020-12-07 03:02

    List<B> and List<A> are invariant type. What you need is covariant type. In this case, it is List<? extends A>.

    0 讨论(0)
  • 2020-12-07 03:02

    While at first glance you might think that

    Class B extends A;
    
    List <B> bList = new ArrayList<B>();
    List <A> aList = bList;
    

    should work, the problem is obvious when you imagine actually using these lists:

    A something = new A();
    aList.add( something ); // Should work because aList is a list of A's
    

    but aList was assigned to bList, so that should be the same as

    bList.add( something ); // Here's the problem
    

    bList.add() takes a B, but something is an A, and an A is not a B!

    And that's why generics should be (and are) strict type safe.

    0 讨论(0)
  • 2020-12-07 03:03

    When you declare a List of items of type A, only items of type A can be added or removed from the List. If you need to include subclasses of A, use the generic wildcard ? extends A to indicate so. Your code should therefore be:

    List <? extends A> aList = bList; 
    
    0 讨论(0)
提交回复
热议问题