Thoughts on Java 5 features

Prompted by the recent Java Posse podcast (episode 79) where they briefly talked about people's experiences with the features that were introduced into Java 5, here are my thoughts on the features I use the most.

  • For each loop : Without a doubt, this is my favourite Java 5 feature. In the majority of cases where you simply want to iterate over a collection of like objects, this is a real time saver because you no longer need to write that boilerplate iterator code. Like many others, I often have to revert back to the old way of doing things, but only if I really have to.
  • Generics : Generics go nicely hand-in-hand with the for each loop, providing you with a way to iterate over objects of a specific type. I like generics a lot and they've really cleaned up the codebase, making it much more explicit and less prone to runtime ClassCastExceptions and the like. On the downside, the syntax is a little verbose. Of course, you don't have to specify the type within angle brackets everywhere, but tools like Eclipse and IDEA start warning you about unsafe conversions if you don't. The other problem that I've encountered a number of times is that it's easy to get tripped up by type conversions and casting now that you have two class types (the containing class and the type) to deal with. That's just part of the learning curve though.
  • Autoboxing : From my experience, autoboxing is both a blessing and a curse. On the positive side, it's another great timesaver and it's really nice to not have to think about conversion between primitives and objects. On the negative, auto-unboxing has caused me a fair amount of grief because of code like this.

    Integer int = null;
    // do some stuff
    SomeObject object = new SomeObject();
    object.aMethodThatTakesAPrimitive(int);


    Bang, NullPointerException for no apparent reason. Nasty, really nasty. Geert Bevin blogged about this 2 years ago, yet it's still tripping us up. On a related note, prior to autoboxing I'd not come across APIs that used the boxed primitives in their interfaces. Now, I'm starting to see this more, which is quite neat because it's easy to represent null values with null rather than a magic number (e.g. -1). On the other hand, you get nasty NullPointerExceptions when you're least expecting them and you still have to put effort into mapping nulls to some magic value where subsequently called APIs use primitives.
  • Concurrency : This is a real gem, with components like the ExecutorService proving to be real timesavers when it comes to build thread pools, etc. If you're thinking of building your own thread pool implementation, take a look at this first!

Lots of organisations and projects that I've seen recently are still using Java 1.4.2 and below, but fortunately my current project is running Java 5 so I'm gradually getting around to using most of the "new" features. With Java 6 just around the corner and Java 5 over 2 years old, it's nice to be using Java 5 commercially at last. Oh well, who wants to live on the bleeding edge anyway? ;-)

Tags :


Re: Thoughts on Java 5 features

"On a related note, prior to autoboxing I'd not come across APIs that used the boxed primitives in their interfaces. Now, I'm starting to see this more, which is quite neat because it's easy to represent null values with null rather than a magic number (e.g. -1)."

I'd still recommend using an actual object to represent 'nothing'.  You can have a wrapper object that can either be 'nothing', or 'something'.

I stole the Maybe type from Haskell (I hope they don't want it back), which quite nicely lets me never have to use null again:

http://functionalpeas.googlecode.com/svn/trunk/src/fpeas/maybe/

Re: Thoughts on Java 5 features

I really like this. I've seen it before but have never really thought about using it on a project. Thanks.

Re: Thoughts on Java 5 features

Hey, if you are reusing a shared ExecutorService e.g. ThreadPool, make sure you are at least aware of the CompletionService API.  Its a real timesaver for ExecutorService and Futures etc.

Re: Thoughts on Java 5 features

I've also just started using Java 5 (glad to hear I'm not the only one).
I found String.format yesterday (it's essentially sprintf).  toString methods can now be written on one or two lines instead of twelve, which is nice.

Hardly touched the other features yet.

Re: Thoughts on Java 5 features

No, you're certainly not the only one and if it makes you feel better, I even heard somebody talking about their Java 1.2 project a few weeks back. When does Java become legacy? ;-)

Autoboxing isn't transitive

The other problem with autoboxing is that it makes the == operator non-transitivie: Equality is no longer transitive Integer a = new Integer(7); int b = 7; Integer c = new Integer(7); if (a == b) System.out.println("a = b"); else System.out.println("a != b"); if (b == c) System.out.println("b = c"); else System.out.println("b != c"); if (c == a) System.out.println("c = a"); else System.out.println("c != a"); It appears that the result of this will be: a = b b = c c != a

Autoboxing isn't transitive

It took me a while to get this and understand the part about transitivity, but I see what you're saying. That's really nasty. c != a is obvious because you're comparing object references. But a == b ... I assume a is being unboxed rather than b being boxed, right?

Autoboxing isn't transitive

With formatting like that, it's not surprising that you didn't get it :-)

The problem is that when you have == between an int and an Integer, it auto-boxes the int and does object equality (with .equals())

However, if the two objects are already integer objects then == does object identity, which returns false.

So comparison only works between int and int, int and Integer, Integer and int, but not integer and Integer. And if you don't know whether it's an autoboxed int or not, you don't know what will happen.

Autoboxing isn't transitive

Autoboxing is transitive. You need to be carful with your names here. Transitivity is a mathematical concept and in your mathematical proof you couldn't use a letter to denote a boxed and an unboxed version and get away with it. It apears that the Java designers think you can in Java though, which is where all the autoboxing confusion comes from.

Autoboxing isn't transitive

There's no concept of 'autoboxing' being transitive or not. A transitive function is one such that if a*b and b*c, then a*c also holds. Equality is defined as a transitive function. The fact that autoboxing confuses (neededlessly) int and Integer types means that it breaks the transitivity of the == operation. Therefore, autoboxing is unsound because it violates a sound mathematical definition; namely, that == must be transitive.


Add a comment Send a TrackBack