Anonymous Classes: Java's Synthetic Closure

Written on 10:50:00 PM by S. Potter

I've been meaning to write this blog post since late last year when I revisited the Java world after a hiatus of adventures in the Ruby and Python worlds. When I was a Java advocate (many moons ago it seems now), I really didn't appreciate the true beauty that is anonymous classes. I saw them as ugly and reducing code readability. Syntactically I still agree with that assessment, but conceptually I couldn't disagree more now. When revisiting Java last year for a client, I found myself really missing blocks from the Ruby world. The following common snippet of code in Ruby passes a block to a method:


  connection = Net::HTTP.new
  connection.use_ssl = true if ssl?
  connection.start do |connection|
    request = yield connection if block_given?
    request.basic_auth(@login, @password) if require_auth
    response = connection.request(request, body)
    handle_rest_response(response)
    response
  end

[This code is taken from the Twitter4R project and is slightly paraphrased.] What we are doing here is wrapping a block within a begin/end API construct. So the previous snippet of code is effectively the same as (and in fact this is the way the above gets executed):

  connection = Net::HTTP.new
  connection.use_ssl = true if ssl?
  connection.open
  request = yield connection if block_given?
  request.basic_auth(@login, @password) if require_auth
  response = connection.request(request, body)
  handle_rest_response(response)
  connection.close
  response

Why is the first so much better from a code maintainability and readability perspective? In my view the main benefits include (but are not limited to):
  • Passing in a block ensures we close the connection (as in the above code example). If we forgot to "end" the block in the first snippet we would get a SyntaxError in Ruby which would remind us to close the block (and thus connection implicitly). Which means less likely to introduce defects related to not closing connections unlike second code example.
  • Putting the code to be executed passed in with a block improves code readability and in my view that is always a good thing. It is more obvious to fellow developers what is going on.
Now in Java we can't simulate the code above in Java syntax...or can we? I suggest with a few more {} and () and ; we can accomplish the same as above. And if we cover our eyes with our hands and squint through the gaps in our fingers, we might be happy with the way it looks (OK, it is ugly, but this is the world of Java people!). Below is an example of a similar technique as the Ruby example above, but this time in Java and related to database transaction (specifically in Hibernate3 below):

// In PersistenceExecutionResult.java we define the following....
public class PersistenceExecutionResult {
  private Object result;
  public PersistenceExecutionResult(Object theResult) {
    result = theResult;
  }

  public Object getResult() { return result; }
  public void setResult(Object theResult) { result = theResult; }
}

// Now in PersistenceExecutor.java we define....
public interface PersistenceExecutor {
  public abstract PersistenceExecutionResult execute() throws Exception;
}

// Now in BaseDAO.java we have the following....
public class BaseDAO {
  public Long create(BaseObject persistableObject) throws Exception {
    final Session session = ....; // get session somehow - irrelevant to demonstration of synthetic closures in Java
    return (Long)executeTransaction(session, new PersistenceExecutor() {
      public PersistenceExecutionResult execute() {
        return new PersistenceExecutionResult(session.save(persistableObject);
      }
    });
  }

  // other stuff, but just adds noise to example.

  protected ExecutionResult executeTransaction(Session session, PersistenceExecutor executor)
    throws Exception {
    Transaction tx = null;
    PersistenceExecutionResult result = null;
    try  {
      tx = session.beginTransaction();
      result = executor.execute();
      tx.commit();
    } catch (Exception e) {
      if (null != tx) tx.rollback();
    } finally {
      session.close();
    }
    return result;
  }
}

Now what on earth is going on? Anyone? Well I will explain in a subsequent posting and compare it to the equivalent code without using anonymous classes to wrap begin/end API constructs. Right now I am too tired and lazy, but I will explain soon, fear not. Notes: the above works with JDK 1.4 because when I wrote this it had to be 1.4 compliant (therefore fancy generic interface definition to DAO was not possible). I have only used JDK 1.5 (aka 5) and not 6. Is there a nicer way of doing this in 6?

If you enjoyed this post Subscribe to our feed

2 Comments

  1. EdLTech |

    Susan
    Your blog rocks. I've just getting started with Ruby; I've been a .NET architect and developer for years.

    The functional equivalents that you call out are so helpful for someone who wants the learn best-practices and terse techniques that Ruby makes so enjoyable to work with in my opinion.

    Thanks

     
  2. Anonymous |

    You even can create & use prototype-based Ruby idioms, http://snippets.dzone.com/posts/show/3378 !

     

Post a Comment