Friday, March 30, 2007

Java :: Static Inner Classes

We all know that Java supports the creation of inner classes. Some people intentionally avoid creating inner classes for many good reasons. And also, one should avoid creating non-static inner classes without a very solid reason. Till now I have never created a non-static inner class except for the anonymous inner classes that I created for event-listeners in GUI programming.

But recently I started using static-inner classes for various purposes and it has tremendously improved my code's readability. Currently I'm using it for two purposes.
  1. Creating Private Utilities
  2. Creating Private Implementations
Creating Private Utilities

What do I mean by "Private Utilities"? We have classes like SwingUtilities, Math, etc. They all contain only "public static" methods and they enforce non instantiability by means of a private constructor. These are public utility classes, but not all the utility classes we create must be public. There are times you will need to have them private. For example, you want to implement your own FileFilter but you don't want to make it public or even package-private. And you also don't want to create that implementation as an anonymous inner class because you think it may clutter the code.

This is a perfect reason for creating a "private static" inner class.

Creating Private Implementations

Just open the source code of java.util.Hashtable and you will see 2 private static inner classes: EmptyEnumerator, and EmptyIterator. When we invoke Hashtable.keys() method, it first checks if the Hashtable has any elements in it. If the number of elements in the Hashtable is 0, it returns an instance of EmptyEnumeration which is a private implementation of java.util.Enumeration interface for empty Hashtable.

These are only a very few applications of static inner classes. I see them as a tool that can make my code more readable, elegant and efficient.

Tuesday, March 27, 2007

Java :: Exceptions :: Nested Exceptions

There is a nice little thing that got introduced in Java 1.4, it's nested exceptions.

Consider the following piece of code:

class LowLevelException extends Exception {
public LowLevelException(String message) {
super(message);
}
}

class HighLevelException extends Exception {
public HighLevelException(String message, Throwable cause) {
super(message, cause);
}
}

public class TryNestedExceptions {
public static void main(String[] args) {
try {
throw new LowLevelException("LowLevelException here.");
} catch(LowLevelException e) {
// While throwing a higher level exception, construct it with
// the LowLevelException as the cause.
try {
throw new HighLevelException("HighLevelException here.", e);
} catch (HighLevelException e1) {
e1.printStackTrace();
}
}
}
}

Let's see the stack trace of the above program:

HighLevelException: HighLevelException here.
at TryNestedExceptions.main(TryNestedExceptions.java:21)
Caused by: LowLevelException: LowLevelException here.
at TryNestedExceptions.main(TryNestedExceptions.java:16)

We also have stack trace of the LowLevelException in the "Caused by:" of HighLevelException's stack trace. This helps us to drill down to the root of the problem. I like the nested exception idea very much. We can nest as many exceptions as we want. For example, if the LowLevelException was caused due to some IOException then while throwing LowLevelException we can nest the IOException.

Naming :: Threads

I find it a good habit to name the threads that we create. For example, in Java the name of the Thread that executes the main method is called 'main'.

It's very useful while debugging or while viewing our log files when we have the thread namea in the log messages. It's especially useful in a multi-threaded application.

public class Main {
public static void main(String[] args) {
// Let's see the main thread's name.
System.out.println("We are currently in: "
+ Thread.currentThread().getName());

Thread thread = new Thread() {
public void run() {
String currentThreadName = Thread.currentThread().getName();

for (int i = 0; i < 5; i++) {
// Printing the user thread's name.
System.out.println("We are currently in: "
+ currentThreadName);
}
}
};

// Setting a name for our user thread.
thread.setName("MyUserThread");
thread.start();

// We're back in the main thread, let's check it.
System.out.println("We are currently in: "
+ Thread.currentThread().getName());
}
}

So, let's all give our Threads a meaningful name :-)

Thursday, March 22, 2007

Naming :: Acronyms and Abbreviations

How often do we have to look into the code when a class name or a variable name contains acronyms or abbreviations in it. For example consider the following class name:

class MyCPPProgram {};

The class name, MyCPPProgram, is correct and fine except that it can be more readable if we declared the class like this:


class MyCppProgram {};

I find the 2nd one more readable than the 1st one. We can also see a similar naming pattern in Java. For example the HttpServlet class. It's not HTTPServlet.