1

Consider following code:

public List<?> concatLists( List<?> ... aLists )
{
    List<?> result = new ArrayList<>();

    for ( int i = 0; i < aLists.length; i++ )
    {
        result.addAll( aLists[i]);
    }

    return result;
}

Compiler (java8) complains in result.addAll(...): "The method addAll(Collection) in the type List is not applicable for the arguments (List)".

But if the result is declared as

    List<Object>

everything is fine.

Until now I assumed that the ? stands for "any type", which - so my assumption - always must be at least an Object. Obviously my assumption is not correct. So I have following questions (which may have the same answer):

  1. Why does the compiler does not allow to addAll() if the target is also a List?

  2. What is the exact difference between:

    List<?>
    List<Object>
    List<? extends Object>
    

Each of this lists cannot contain something which is NOT an Object.

Edited to clarify

consider following code:

    List<? super Object> superObject = new ArrayList<>();
    List<? extends Object> extendObject = new ArrayList<>();
    List<?> plainObject = new ArrayList<>();
    List<Object> object = new ArrayList<>();

    Object obj = new Object();
    superObject.add( obj );     // valid
    extendObject.add( obj );    // ERROR
    plainObject.add( obj );     // ERROR
    object.add( obj);           // valid

    Integer aInt = Integer.valueOf(1);
    superObject.add( aInt );    // valid
    extendObject.add( aInt );   // ERROR
    plainObject.add( aInt );    // ERROR
    object.add( aInt);          // valid

    String str = "hello";
    superObject.add( str );     // valid
    extendObject.add( str );    // ERROR
    plainObject.add( str );     // ERROR
    object.add( str);           // valid

    superObject.addAll( superObject );  // valid
    superObject.addAll( extendObject ); // valid
    superObject.addAll( plainObject );  // valid
    superObject.addAll( object);        // valid

    extendObject.addAll( extendObject );    // ERROR
    extendObject.addAll( superObject );     // ERROR
    extendObject.addAll( plainObject );     // ERROR
    extendObject.addAll( object);           // ERROR

    plainObject.addAll( plainObject );  // ERROR
    plainObject.addAll( superObject );  // ERROR
    plainObject.addAll( extendObject ); // ERROR
    plainObject.addAll( object);        // ERROR

    object.addAll( plainObject );  // valid
    object.addAll( superObject );  // valid
    object.addAll( extendObject ); // valid
    object.addAll( object);        // valid

    Object o;
    o = superObject.get( 0 );  // valid
    o = extendObject.get( 0 ); // valid
    o = plainObject.get( 0 );  // valid
    o = object.get( 0 );       // valid

Each of this list can only contain Objects (or derivations of it) which is proven by the valid get calls on each of them.

Because I always deal with Object, I do not see any reason why the errorneous lines should not be allowed, especially the ones where the plainObject List (without super or extends) is involved.

Heri
  • 4,368
  • 1
  • 31
  • 51
  • See also http://stackoverflow.com/questions/24756464/unable-to-add-object-to-generic-list-using-wildcard and http://stackoverflow.com/q/7906764/1743880 – Tunaki Aug 09 '16 at 13:34
  • Following your links above: All deal with either "? extends T" or "? super T". I just have this ?, the list cannot contain something else than an Object (or a derivation of it). It is never assigned to a more specific type, i.e. I never can try to get a String from the List where there is a Number in it. So I think my question is still valid. Consider my edit. – Heri Aug 09 '16 at 19:44
  • You may want to ping JensSchauder directly to inform him of your comments. I don't see any edit though. – Tunaki Aug 09 '16 at 19:52
  • Just saved my edits – Heri Aug 09 '16 at 20:04
  • [You will want to read this.](http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html) – Voo Aug 09 '16 at 20:12
  • Thanks for the link. I think I understand everything there. Except: "The unbounded wildcard looks like " ? " and stands for the family of all types". I cannot imagine a type which is NOT an Object. So why I cannot add a Number to a List typed with th '?' ? – Heri Aug 09 '16 at 20:36
  • 1
    Because `List>` doesn't mean "List of objects". It means "List of some unknown type out of the set of all types". `List foo = ...; List> bar = foo;` is perfectly valid code (a string is a type from the set of all possible types after all). Obviously if you could now add a number to bar you would have a problem. Since every type in your set of all types has object as its supertype (or is object itself) you can write `Object o = bar.get(0);` though. – Voo Aug 09 '16 at 21:21

0 Answers0