Generics don't write Bad Code, people do.
Of the big changes to the JLS coming with JDK1.5, generics are definitely the one I'm least psyched about. The debate about this has raged for years, so I won't waste keystrokes rehashing arguments about how completely useless and ugly they are. Those arguments are now not only tired but moot as well; ready or not, generic types are here.
So, what are they going to do the code we have to deal with every day? Here's one case I worry about - consider the following:
import mypackage.Widget;
public interface MyBean {
/**
* Returns an unmodifiable List of the Widgets
* on this bean. The objects in the list will
* always be instances of class Widget, but for
* some reason, I just don't feel like returning
* you a nice typed array per the Java beans spec.
*/
public List getWidgets();
}
I think most people agree that this isn't a great API design, but sometimes it seems like the only argument against it that really sticks is that it isn't typesafe. Enter generics:
import mypackage.Widget;
public interface MyBean {
/**
* Returns an unmodifiable List of the Widgets
* on this bean. Now it is perfectly typesafe
* so why should I bother with an array anymore?
*/
public List<Widget> getWidgets();
}
Well, I would suggest that this is still pretty broken. It's still a bad contract. Even in this simple example, it exposes a lot more surface area with that List than necessary. This is why it relies on the somewhat hackish notion of an unmodifiable List. Also, the semantics of calling methods on that List are difficult to clarify, especially when MyBean's internal state changes.
(Moreover, it makes introspecting MyBean a bit more gross. Now you have to
get the return type of the getWidgets method, check if
Collection.class.isAssignable to it, and if so,
call Class.getTypeParameters()[0] to figure
out that it is a List of Widgets. I'd rather just call
Class.getComponentType and be done with it).
But I'm afraid that we probably be seeing more of this kind of thing in the near future. Generic types may unleash a flood of bad design, as people start stamping out templated types without a thought for design minimization. But hey, as long as you don't have to cast, it's all good, right?
