Practically Agile

Using Agile in less-than-perfect situations since Y2K

Java No Longer My First Choice

The last few months have been pretty mixed for me as a programmer. I have been a Java developer since the 1.0 days circa 1996-1997. (Netscape IFC anyone?) For me, it was a great change from C and C++. That’s twelve-ish years with most of my professional work in one language. For the last couple of years, I have been doing a bit more project and people management and less programming. When I have done programming, it has been largely Ruby, HTML/CSS, Javascript and even some C#.

Therefore, it was with a great deal of happiness that I was able to take on a much more developer-oriented role in my latest Java project. I was back in the groove. There were some annotations I had to learn or re-learn, but they mostly made sense. I was concretely producing value again rather than just enabling others to do so.

Over time, I found myself stumbling over difficulties that were entirely Java-centric. I kept running into problems with Generics. Java reflection was a morass of generics and class-casts. I found myself every single day having to say, “I hate Java Generics.”

// a sample usage of generics
// based on a real usage in my current project

Map<Class<ReasonableClassName>, ReasonableClassName> objectByType =
     new HashMap<Class<ReasonableClassName>, ReasonableClassName>();

// pre 5.0
Map objectByType = new HashMap();

I was never a fan of the Generics proposal for Java 5. It is just overly verbose as the example above shows. The Java 5 version provides type safety, but at what cost? Fortunately, back then, I was able mostly to ignore this. I only really used generics when using collections, and I tend to wrap those in more domain-friendly objects. That practice also meant I didn’t really need generics in the first place, but c’est la vie. I was happy enough.

In the current project things are somewhat different. I am building upon legacy code, using a lot of collections in a single class, and using a lot of reflection. I found APIs that were inconsistent in their use of Generics. For example:

// from java.lang.Class

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) {
    // ...
}

public Constructor<?>[] getDeclaredConstructors() {
    // ...
}

Note that when getting a single declared constructor, it returns a properly specified constructor that will create something of the type of the class. However, if I want the full list of constructors, the array returned now doesn’t know what type the created objects would be. There is a reason for this: having a “genericized” array is “bad”. Don’t ask me why. Folks much more familiar with the generics implementation struggle to understand the reason for this.

Regardless, it means I need to cast the result. Is that not what generics were supposed to save me from? This also could lead (depending on the context) to entirely unnecessary type checks or even a compiler warning for “unchecked type cast”. In short, what I have found is that for every benefit generics provide, there are multiple hoops to jump through or other problems that detract from it. Yes, some of this is caused by the implementation and not the concept, but that makes me think worse of Java, not better.

There is also a push to add more “safety” to the language through annotations and other means. Java cannot take more overhead pushed into doing simple things. I am far from the only one to think this. As an example, see this post from almost a year ago.

I am pretty fluent in Java (sans generics) at this point. It is by far the language I know best. However, I now realize that while Java may continue to be what I am paid to do, my personal first choice will have to be something else. Using the language is too much work; it is too cumbersome. I like Ruby already, but maybe I’ll delve deeper into Scala. At least both of them run on the JVM.

. 10 Feb 09 | Programming | Comments (3)