Java Anonymous Inner Classes

May 26, 2007

Just the other day I stumbled across some weird syntax in some Java code that I’ve never seen or read about. I started to research it and discovered it’s called an anonymous inner class. Basically, it’s defining a one-time use object.

The code I was looking at is used to establish a connection to an SSL website. It just so happens that in my scenario, the website was using a self-signed certificate and in order for the HttpsURLConnection to connect, I needed to define a HostnameVerifier to force the hostname to be valid. Here’s the static function:

public static void setDefaultHostnameVerifier(HostnameVerifier v)

Now I need to create an object that implements the HostnameVerifier interface who’s definition looks like this:

public interface HostnameVerifier {
    boolean verify(String hostname, SSLSession session)
};

So, if I were to do this the old way, I would need to do this:

public class MyHostnameVerifier implements HostnameVerifier {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};

And then in my code call:

MyHostnameVerifier mhv = new MyHostnameVerifier();
HttpsURLConnection.setDefaultHostnameVerifier(mhv);

Yuck! Why would I want to create MyHostnameVerifier if I’m only going to be using it once? That’s where anonymous inner classes come in.

HttpsURLConnection.setDefaultHostnameVerifier(
    new HostnameVerifier() {
        public boolean verify(String urlHostName, SSLSession session) {
            return true;
        }
    }
);

This is much cleaner. What if we wanted our verifier to check a Hashtable to see if a specific host is blocked. In order for our anonymous inner class to be able to access variables outside its scope, the variables must be final.

final Hashtable<String,String> blockedHosts = new Hashtable<String,String>();
blockedHosts.put("10.0.0.1", "10.0.0.1");
blockedHosts.put("10.0.0.2", "10.0.0.2");
blockedHosts.put("10.0.0.3", "10.0.0.3");

HttpsURLConnection.setDefaultHostnameVerifier(
    new HostnameVerifier() {
        public boolean verify(String urlHostName, SSLSession session) {
            return !blockedHosts.containsKey(urlHostName);
        }
    }
);

You need to be careful when you final your outer variables. The classic example is a outer variable used to keep track of a count. If you simple do final int count = 0;, you will not be able to update the count. However, if count was an array, the array is final, but the elements within are not:

final int[] count = new int[1];

Then you would just access count[0] every time you wanted to change its value.

As you can see, Java anonymous inner classes are fun!


No Comments

No comments yet.

RSS feed for comments on this post. TrackBack URL

Sorry, the comment form is closed at this time.