I’m a reasonably advanced user of Java and I plunged into Java 5 and generics in September. I’ve written a fair amount of code in it over the last 4+ months, including some API and framework-y type things. In general, I’d say it improves life marginally for the user of a component (in the most generic sense – could be interface, class, set of classes, etc) by making many signatures clearer and their usage (usually) simpler due to the removal of previously needed (and not always obvious) casts.
For the component implementer, I find generics can be a royal pain. At a minimum, they typically mean more typing and more complexity (at least from a language technicality point of view). At their worst, I find certain things do not “just work” the way I expect them to. Sometimes I am able to quickly track understand and modify my code (after a minimal amount of research on something like Angelika Langer’s Generics FAQ or the Java documentation). A couple times (sorry, no examples at hand) I’ve been completely stumped and eventually just gave up and wrote the code a different way.
My overall impression has been that while some code is simpler and that’s nice, that code was already simple (if verbose). Code that was complicated is now WAY more complicated and sometimes quite difficult for someone else to pick up and understand what the heck is going on. In balance, right now I’d say it’s a step backwards.
I’m looking forward to picking up the book Weiqi is reading (Java Generics and Collections) as soon as I finish reading Java Concurrency in Practice. Maybe I’ll learn a bit more about the cases that stumped me. In general I find a lot of unanswered questions looking at the Java collection API (like this question on indexOf) that I can’t answer definitively even after mild thought and research.
On the other hand, I can enthusiastically say that enums rock! I love them more every day.