For a long time, I was unhappy with Java generics, a language feature that was introduced in Java 1.5. Java generics are supposed to give Java programmers the ability to write code with greater type safety. Unfortunately, Java generics have also introduced a lot of complexity into the language:
Here are some of my main complaints with generics:
#1 Confusing and difficult-to-understand syntax.
Here is an example:
class Box< T extends Comparable<T> & Cloneable> implements Comparable<Box<T>>, Cloneable
I would prefer not to parse the class declaration for several minutes to figure out what is going on.
#2 Java generics do not seem to be generic.
Map map = new HashMap();
The Map declaration is nice, clean, simple, and GENERIC. It will contain any key value object pair.
Map<String,String> map = new HashMap<String,String>();
The Map declaration is no longer generic but rather specific and now must hold String for both key and value. That is not generic.
#3 Poor cost-to-benefit ratio.
Much complexity has been introduced into the language as a result of generics that is time consuming to learn.
Fortunately, there are resources like Angelika Langer's 425-page FAQ. Yes, it is really 425 pages. I consider this to be one of the most valuable Java resources on the web. Indeed, if her FAQ did not exist, we would all have given up by now on Java generics. (I am hoping to read the whole thing and I am about a 1/3 of the way through it.)
But on the flip-side, if it takes me 425 pages to understand something, I'd better be getting some really great features. I do not anticipate these benefits with Java generics.
I realize that much of the complexity associated with Java generics is to accommodate backwards compatibility concerns. Brian Goetz wrote a nice article that touches upon this issue and others surrounding Java generics. Maybe if the powers that be were to get rid of raw types, generics could be simplified. The Java Language Specification states that raw types are strongly discouraged and may not be supported in future versions of Java.
#4 Did I mention the syntax?
Here is an example of a Collection data structure:
Collection< ? extends Pair<String, ?>> c = new ArrayList<Pair<String,?>>();
I would prefer not to study the Collection declaration for 10 minutes to figure out what it holds.
Or here is one I really like:
Enum<E extends Enum<E>>
Huh? I feel my mind over-heating.
Actually, this is explained in Angelika's FAQ.
Experienced developers have been struggling with generics. Where does that leave junior programmers attracted to Java supposedly because it is simpler and more elegant than other OO programming languages?
The whole thing almost smells of a political dispute within the Java language designer community. Why didn't they introduce generics from the start instead of adding it piecemeal halfway through? Is the state of type theory really that much more advanced than in 1995 when Java was introduced? Indeed, this would have made things a lot easier since a large part of why Java generics are so confusing is because of backwards compatibility issues.
Despite all these misgivings, I have been moving over to generics and in some cases genericizing some of my APIs. Part of the reason I am doing this is that I am forced to. If I want to be a decent Java programmer, I have to know how to use generics. I've heard that it is even starting to crop up in job interview questions.
Also, it does seem to make code a bit more readable if the type parameters are simple.
List<Integer> list = new ArrayList<Integer>(); //Not so bad to understand.
The new Guice IOC container from Google also makes heavy use of generics. I haven't used Guice yet, but I look forward to seeing how Java generics play out in this context.
I am starting to get used to generics, but I also feel like I have a long way to go before I can completely master this challenging subject .