今更ながらGenericsのすごさに驚嘆しているわけで。
ActiveObjectsの中にはトランザクションを保証するためのTransactionクラスがある。Transactionクラスのシグネチャはこんな感じ。
public abstract class Transaction<T>; public T execute() throws SQLException; protected abstract T run() throws SQLException; protected final EntityManager getEntityManager();
で、使い方はこんな感じ
EntityManager manager = new EntityManager(provider); Person p = new Transaction<Person>(manager){ @Override protected Person run() throws SQLException { // このときINSERT文発行! Person p = manager.create(Person.class); p.setName("Hiroki Kondo"); // このときUPDATE文発行! p.save(); return p; } }.execute();
Transactionクラスは抽象クラスなので、こんな感じに匿名クラスを作って使ってやる訳ですね。PersonクラスをGenericsのTの部分に指定する事で、runメソッドの返値がPersonになっている訳ですよ。executeメソッドの中でrunが呼ばれて、その結果を返すようになっているので、Transactionの外でPersonのインスタンスが受け取れるわけです。無事にrunメソッドが終わればcommit、SQLExceptionなどが飛べばrollbackします。
Collectionクラスでよく使っているGenericsですが、匿名クラスの返値をオーバーライドで指定して使う方法は見たことがなかったんでスゲーと驚いている訳です。これだからコードリーディングは止められません。