Wednesday, December 23, 2009

"That" Java example and preaching to the converted

There is one example of Java code that keeps coming up. I have seen variants of it at conference presentations several times, in Venkat Subramaniam's Programming Groovy and most recently in an essay by Neal Ford in The ThoughtWorks Anthology. This example compares Java with a scripting language, and goes usually something like this (here I combine all the worst practices from the books in one example):

JAVA VERSION:

import java.io.*;

public class ReadFile
{

public ReadFile(String path)
{
BufferedReader reader = null;
try
{
reader = new BufferedReader(
new FileReader(path));
String line = null;
while((line = reader.readLine()) != null)
{
System.out.println(line);
}
}
catch(FileNotFoundException ex)
{
ex.printStackTrace();
}
catch(IOException ex)
{
ex.printStackTrace();
}
finally
{
try
{
if (reader!=null)
{
reader.close();
}
}
catch (IOException ex)
{
//Ignore
}
}
}

public static void main(String[] args)
{
new ReadFile("thoreau.txt");
}
}


GROOVY VERSION:

println new File('thoreau.txt').text


Wow, 1 line instead of almost 50! Java must really suck! The problem with this is that the Groovy version is obviously just a one-off, there is no attempt to make a reusable module or do robust error handling. If there is an error, the program just terminates with en error message. We can do exactly the same with the Java version and cut down the number of lines significantly if we just throw the exception. We can reduce the number of lines even more if we use a "modern" (1.5) API and the Java coding conventions for where to place brackets, etc:


import java.io.File;
import java.util.Scanner;

public class ReadFile {

public static void main(String[] args) throws Exception {
File in = new File("thoreu.txt");
String contents = new Scanner(in).useDelimiter("\\Z").next();
System.out.println(contents);
}

}


It can be made a one or two lines shorter still, (at the price of a dependency on a big jar) if you are are willing to use an external library such as Apache Commons IO. Or I could have squeezed the three lines of logic into one, but I think this is a reasonable trade off between readability and verbosity. But this new and improved example is still much longer than the Ruby/Groovy/Scala/etc versions (especially if you count characters instead of lines); and arguably less clear (What's a scanner? What does "\\z" mean?).

The problem with using the original Java example is that will mainly convince those who are firmly in the "Yeah, Java totally sucks" camp. Even a very junior Java developer, who is curious about learning about a new language will see that the original example is either
a) Written by a rank amateur (unlikely considering the caliber of the authors) Or -
b) Wildly exaggerated to make Java look as bad as possible.
And that will make them less receptive to the text as a whole. With the number of active Java programmers probably (still) in the hundreds of thousands, alternative languages have a large number of possible recruits and allies. I would prefer to see a better example to convince them that it is worthwhile to look at other languages.