Tiger,Tiger,Tiger

Java 5.0 Tiger (開発者ノートシリーズ)

Tigerの詳細について、余り見ない様にしてきた訳では無いけれども、
全体を俯瞰してなかった様な気がするので買ってみたり。

結構良い感じ。電車の中で読み易い厚さです。ハイ。


んで、ちょっと重要そうな事があったので、メモ。


アノテーション。特に、Retentionメタ・アノテーション
メタアノテーションは、アノテーションアノテーション。みたいな。
これは、コンパイラが対象のアノテーションをどう扱うか決められるらしい。
指定出来る値として3つあるます。

リフレクションで読み出す為には、RUNTIMEを指定しなければならないらしいです。

僕にとってちょっと意外だった、と言うか僕が知らなかっただけですが、.classファイルにメタデータがキチンと取り込まれる事。
TigerGenericsは、コンパイル時に解決してそれでオシマイなので、アノテーションもそんな感じかな…とか、思ってました。
まぁ、それだとかなり早いうちから取り沙汰されていたDeprecatedアノテーションが実現不可能な訳ですが…
深く考えてなかったっちう事ですな、僕が。


ちょっと疑問なのは、何故Genericsメタデータとしてコンパイル済みクラスに持たないのか?です。
だってさ、java.lang.annotation.ElementType.LOCAL_VARIABLE
なんてのがあって、ローカル変数に対してもアノテーション出来るんなら、コンパイル時にGenericsな情報をメタデータとして持ってても良く無い?


んで、S2DAOも、このアノテーションを使った実装が登場する日もいつかはあるでしょう…、ってな感じでチト考えてみたり。

Beanはこんな感じ?

@Table("EMP")
@Serializable
public class Employee {
    @Column("EMPNO")
    private long employeeNo;

    @Relation(relno=0,relkeys={"deptno:deptno","ename:dname"})
    private Department department;

    public long getEmployeeNo() {
        return this.employeeNo;
    }
    public void setEmployeeNo(long empno) {
        this.employeeNo = empno;
    }
    
    public Department getDepartment() {
        return this.department;
    }
    public void setDepartment(Department dept) {
        this.department = dept;
    }
}

んで、対応するDaoはこんな感じ?
Genericsを使って複数件データが返ってくる時のコードもちょっとカッコよさげに書いてみたり。

@Bean(Employee.class)
public interface EmployeeDao {
    @Args({"empno"})
    public Employee getEmployee(int empno);

    @Query("sal BETWEEN ? AND ? ORDER BY empno")
    public List getEmployeesBySal(Float minSal, Float maxSal);
}

ここで問題。EmployeeDao#getEmployeesBySalをこんな感じに書いてしまっても、
実行時例外、恐らくClassCastExceptionが発生するまで分かりせん。

    public List getEmployeesBySal(Float minSal, Float maxSal);

Genericsな情報をメタデータとして持ってれば、
適切な非チェック例外を仕組みとして送出する事も出来たのにねぇ…。みたいな。
まぁ、こんな風に書いたら、どっか別な場所でコンパイルエラーになる筈ですが…きっと…。


メタデータに対応する事で、S2DAOのコードベースは確実に綺麗になるけど、
ユーザ側のメリットって何だろう?…と思ったり。
S2独自なテクノロジでは無く、標準APIに則った形での実装に対してメリットを感じるんなら価値はあるかなぁ…とか。
新規にS2DAOを勉強する人には綺麗に見えるかもしれないけど、
旧来のS2DAOに慣れてる人には、新しい表記が増えるだけであんまりメリットが無いのかなぁ…。
Tiger以後でしか動かないし。


只、アノテーションを記述する時の型のチェックがコンパイル時にかかるってのは、
生産性の面から見てちょっと良い感じかも…。
例えば、今だと、

    // 型が間違ったアノテーション。その1
    public static final long department_RELNO = 0L;

    // 型が間違ったアノテーション。その2
    public static final String department_RELNO = "0";

    // ちなみに、大文字小文字がずれてるだけなら、ちゃんと動きます。
    public static final int department_relNo = 0;

こんな風にアノテーションを書いちゃっても、
IllegalArgumentExceptionが起こるだけで何故間違ってるのか、直ぐには理解出来ない人も居るかもしれないし。


書いてて思いついたんですが、もう1つ、生産性におけるメリットがあった。
それは、アノテーションの記述をeclipseとかIDEの類がサポートしてくれる可能性が高いって事。
こんな感じで、アノテーション書いてる途中で、Ctrl+Space押したら続きを入力補完してくれるなら、良い感じかも。

    @A // ここで、Ctrl+Space。残りの、rgs({}) を補完。みたいな。
    public Employee getEmployee(int empno);


書籍以外のネタ元。