Domanda

I've been testing supertype generics with Java, but I've come to a roadblock. This is the sample code I was testing:

import java.util.*;

class GenericTests {
    public static void main( String[] args ) {      
        List<B> list3 = new ArrayList<B>();
        testMethod( list3 );
    }

    public static void testMethod( List<? super B> list ) {
        list.add( new A() );
        list.add( new B() );
    }
}

class A { }

class B extends A { }

When compiled, the error is:

GenericTests.java:20: error: no suitable method found for add(A)
            list.add( new A() );
                ^
method List.add(int,CAP#1) is not applicable
  (actual and formal argument lists differ in length)
method List.add(CAP#1) is not applicable
  (actual argument A cannot be converted to CAP#1 by method invocation conve
rsion)
where CAP#1 is a fresh type-variable:
CAP#1 extends Object super: B from capture of ? super B
1 error

I thought that given the lower bound of B, you could add any supertype? Or does this only apply to the references (i.e. arguments within the method signature) because allowing supertypes would break the type checking?

È stato utile?

Soluzione

The declaration List<? super B> list says that list is a List of objects of some type that B inherits from. But this type need not be compatible with A. Suppose the hierarchy had been:

public class A {...}

public class C extends A {...}

public class B extends C {...}

Then, list could be a List<C>. But then list.add(new A()) is illegal. An instance of A is not an instance of C. The compiler only knows that instances of B or a subclass can be added to list.

Altri suggerimenti

You got the idea of ? super B differently than it actually is. What super do here is something like bellow:

public static void main( String[] args ) {      
    List<B> list3 = new ArrayList<B>();
    testMethod( list3 );

    List<A> listA = new ArrayList<>();
    testMethod(listA); --> U can pass a list of A
}

public static void testMethod( List<? super B> list ) {
    list.add( new B() );
}

This answer discuss the fact in detail.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top