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 HashtableblockedHosts = new Hashtable (); 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!
Comments
Post new comment