tags:

views:

101

answers:

2

Does anyone have a good explanation why the ? extends syntax has to be used in generics? I know what the syntax enforces but it just doesn't seem to be consistent with how non-generic type checking is done in Java. For example:

void someMethod() {
    List<String> strings = new ArrayList<String>();
    doSomethingWithStrings(strings);
    doSomethingWithObjects(strings); // << This doesn't compile
}

void doSomethingWithStrings(Collection<String> strings) {}

void doSomethingWithObjects(Collection<Object> objects) {}

That will have compile errors where commented, while in this next example there are obviously no compile errors:

void someOtherMethod() {
    String string = "worksInBothPlaces";
    doSomethingWithAString(string);
    doSomethingWithAObject(string);
}

void doSomethingWithAString(String string) {}

void doSomethingWithAObject(Object object) {}

I know the first block can be fixed by changing the second signature to

void doSomethingWithObjects(Collection<? extends Object> objects) {}

but again that doesn't seem consistent with out type checking is done elsewhere. Is there some clear example where without ? extends some generic class would be harder or even impossible to write.

+1  A: 

Quite simply, because a Collection<String> is not the same type as a Collection<Object> and it is not a subtype of it either.

That is Collection<String> is not a Collection<Object>, where as String is a Object.

The detail as to why this is so is quite complicated, and you would be best served by referring to Angelika Langer's FAQ on generics in Java.

Software Monkey
+3  A: 

Basically the generic can't confirm reallocation stuff.

void AddSomething(Collection<Stuff> object)
{
  object.Add(new Stuff());
}

will fail if you try to call

AddSomething(new Collection<ChildStuff>())

because you can't add a Stuff to a ChildStuff collection.

For the compiler/runtime/whatever to know that your function won't do anything like that, it needs to be told that it's okay to accept subtypes, and that's done through the ? extends syntax.

Tanzelax
Ah, well that makes perfect sense to me. I knew there would be some simple example I wasnt thinking of. Thanks
Yanamon