Java 1.5

I started reading Java 1.5 Tiger: A Developer's Notebook on Safari a few days ago.  Java 1.5 is the next iteration of the Java language - it's about as radical a change to Java as C# 2.0 is, adding some of the same stuff (Generics) and some stuff that C# already has (Attributes), as well as adding some brand new stuff (like being able to override a method and change only the return type).

I use to think that Java was the 'purist' language and C# was the 'pragmatist' language - I think I got that idea from the way that Java forces you to catch exceptions, while C# doesn't force you to (or even warn you that you're not catching them). 

However, I recently got burned by Java when I wrote an application that, as part of it's operation, occasionally needed to send email, and when I deployed the application, I forgot to include one of the jars that the mail support needed (a .jar file is a collection of classes, similar to a .NET assembly).  Nothing warned me that I was missing a jar - so the application ran fine until it needed to send an email, at which point it would throw a ClassDefNotFound exception and restart. 

Java has a much less rich standard framework than .NET does, so I've found Java programming to be a frustrating game of 'hunt the jar'.  Missing a jar upon deployment seems like it would be a common thing to do. 

Anyway, Java 1.5 adds some new stuff, but the design of some of this new stuff seems inelegant.  For example, here's the C# syntax for the langauge construct that lets you iterate through the items in a collection:

  foreach (Item i in myCollection)

Here's the Java 1.5 version:

  for (Item i : myCollection)

The C# version is, in my opinion, a better design.  Personal preference I guess.

Another thing that seems less clean is the new StringBuilder class, which is an exact copy of the StringBuffer class, but not thread safe.  If you want a faster StringBuffer, use StringBuilder - you can even search/replace the name, because the interface is identical.  But doesn't creating a new class just to change an implementation detail seem wrong? 

Their new syntax for specifing sprintf style formatting is bizarre too.  It's a lot like sprintf, which is good for C programmers, but it doesn't seem to let you specify argument position other than to say 'reuse the previous position'.   So you can say:

  formatter.format(“%s's name is %<s.  He is a %s.”, “Woofy”, “Collie”);

The C# syntax for this would be “{0}'s name is {0}”.  Less C-like but much more useful because now you can do something like this:

  string.Format(“{0}'s name is {0}.  He is a {1}.“, “Woofy”, “Collie”);

  string.Format(“My {1}'s name is {0}.“, “Woofy”, “Collie”);

By changing the format string you can change the position that the arguments are drawn from.  This is incredibly useful in internationalization, because in another language, the order of the arguments will often need to be different.  It looks like with Java 1.5 you'll need to find another way of doing string formatting if your source strings are going to be translated.

The difference in the implementation between generics in Java 1.5 and C# 2.0 has been covered well elsewhere so I won't do that here, but it's worth reading.  That's biased of course, since it's by Anders Hejlsberg, the designer of C#.

There are plenty of other good language features in Java 1.5 - boxing and unboxing of native types for example - so it seems like a good upgrade for Java programmers, but I don't see anything that C# 2.0 doesn't already cover.  The languages are still close enough that it won't be language features that makes you choose between Java and .NET.