読者です 読者をやめる 読者になる 読者になる

今更ながら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ですが、匿名クラスの返値をオーバーライドで指定して使う方法は見たことがなかったんでスゲーと驚いている訳です。これだからコードリーディングは止められません。