Search code examples
javageneric-programming

Why can't I put an object of superclass of B into Container<? super B>?


I have the code below. It seems that I can't put an object of class Nonlife that is a superclass of class Vehicle into a container of type Collection<? super Vehicle> ALTHOUGH there is a keyword "super" in the wildcard type, and only objects of class Vehicle and SUV that is a subclass of class Vehicle are feasible. Could someone give me some advice?

public class SUV extends Vehicle

public class Vehicle extends Nonlife implements Externalizable

public class Nonlife extends Thing

public class Thing implements Comparable<Thing>, Serializable

public class SupperWildcardTest20200830 {
    
    public static void main(String[] args) {
        Collection<Thing> coll = new ArrayList<>();
        appendVehicle2Collection(coll);
        appendSuv2Collection(coll);
        for (Thing el: coll) {
            System.out.println("" + el);
        }
    }
    
    public static void appendVehicle2Collection(Collection<? super Vehicle> coll) {
        coll.add(new Vehicle());
    }
    
    public static void appendSuv2Collection(Collection<? super Vehicle> coll) {
        coll.add(new SUV());
    }
    
    public static void appendNolife2Collection(Collection<? super Vehicle> coll) {
        /**
         * incompatible types: Nonlife cannot be converted to CAP#1
         *  where CAP#1 is a fresh type-variable:
         *    CAP#1 extends Object super: Vehicle from capture of ? super Vehicle
         */
        coll.add(new Nonlife());
    }
}

Solution

  • The only thing you know for sure about Collection<? super Vehicle> is that it is a collection of Vehicles, or a collection of a supertype of Vehicles. So the only thing you know for sure that you can put into this collection are Vehicles. So you are allowed to pass a Collection of NonLifes to the method, but you may still only put Vehicles or subtypes into the collection within the method.

    In general: with super, you can put values of the mentioned type in it, or subtypes. With extends you can retrieve the mentioned type from the collection, or retrieve them as a supertype.