Hacker News new | ask | show | jobs
by mkross 5699 days ago
Wait, generics support co/contra variance through the 'extends' and 'super' keywords. e.g. Collection<? extends Foo>
1 comments

I suppose so; but not in the sense I was thinking of: a Collection<Firetruck> is not a subclass of Collection<IVehicle> (and it is impossible for you to create your own generic class where this type of relationship would be true).
While Collection<Firetruck> has an indeterminate relationship with Collection<IVehicle>, this is good! If Collection<String> was a subclass of Collection<Object>, you could fill the collection with Strings and then pass it off to someone who is using it for Objects and adds in his own Integer. Now your collection is borked. :(

If you find yourself wanting to pass in Collection<Firetruck> to a method that only accepts Collection<IVehicle>, this usually means that the method isn't correctly typed. The rule of thumb for using 'super' and 'extends' is "Producer extends, Consumer super" or PECS. By applying this, the typing problem should go away, as your method is now accepting Collection<T extends IVehicle> and possibly returning Collection<? super T>, so you can both pass in your Collection<Firetruck> and reassign to a different variable of type Collection<Firetruck>. :)

(I think Josh Bloch wrote up a decent blog post about the PECS principle a couple of years ago. It might be worth reading for more information.)

As I enjoy the benefits of immutable data structures and read-only interfaces, it is absolutely not an unmitigated good. Replace "Collection" with "Iterator" above, and the borking you mention is impossible ...