Thursday, September 3, 2009

Java and the Impossible Generic List

Since Java 1.5, I've been used to writing List<Class>, allowing the compiler to insure type safety of collections.

There's one issue with this, however.

let's say you have an interface. We'll call it TheInterface.

Java is more than content with allowing you to say List<TheInterface>

So what?

The problem with that syntax is that it says that the contents of the List will always be items whose exact type is TheInterface.

But it's an interface. So there will never be any of those.

Stupid Java.

The solution is simple: you're supposed to say List<? extends TheInterface>. This lets the list contain any objects that implement the given interface, which is almost assuredly exactly what you want.

So why isn't List<TheInterface> a compile error?

Bueller?

2 comments:

tbright said...

Why is it stupid?

If you say List then it can contain ANYTHING that implements that interface.

The same works for subclasses. If you say List then your list can contain Integer or anything else that is a Sub-Class of Number.

Nick said...

No, List<CLASS> means that the list can only contain instances of CLASS. If you want the list to contain objects that can include sub-classes of CLASS, you must say List<? extends CLASS>

Because of that, the implication is that List<interface> is impossible, because you can never have an instance of the class. You can only have an instance of an object that implements the interface. That's <? extends interface> not <interface>.