Lombok すげー

面白いライブラリを見つけたのでメモ。

lombokというライブラリで、こいつが何をするかというとアノテーションを付けるとアクセサ(getter,setter)やhashCode、equalsやtoStringがバイナリレベルで自動生成される(ソースコード上には現れない)というもの。Stream系のclose処理も自動でやってくれちゃう優れもの!

Project Lombok
Java の冗長性を排除する手軽な方法
NetBeansでlombokを使う - Sacrificed & Exploited

環境に関してですが、NetBeans7+Mavenの場合はlombokの依存性をpomに追加するだけで簡単に使えるようになりました。
pom.xml

<dependencies>
   <dependency> 
        <groupId>org.projectlombok</groupId> 
        <artifactId>lombok</artifactId> 
        <version>0.9.3</version> 
        <scope>provided</scope> 
    </dependency>
</dependencies>

例えば下記Employeeクラスがあったとして

public class Employee {
    private String name;
    private int age;
}

上記を使うクライアントクラスが下記だとするとgetNameメソッドとか呼び出しちゃったりした日にはコンパイラーに怒られちゃうのがJavaであって、そこらへん(アクセサとか書かないといけない)とかが「Javaダセーw」とか言われちゃう原因の一つだったりするわけです><

public class App {
    public static void main(String[] args) {
        Employee e = new Employee();
        e.getName(); //こんぱいるえらー
    }
}

しかし、lombokを使えば上記Employeeを下記のように修正すると上記コンパイルエラーから開放されるわけですね。

import lombok.Data;
public @Data class Employee { //@Dataを付けるだけ
    private String name;
    private int age;
}
public class App {
    public static void main(String[] args) {
        Employee e = new Employee();
        e.getName(); //エラーにはなりません。
    }
}

(もちろんEmployeeを保存するだけでApp側では認識されるようになります。)

@Dataはgetter、setter、hashCode、equqals、toStringを生成し、final定義したフィールドはそのフィールドを引数にとるコンストラクタの生成を行います。
ちなみにgetterのみやsetterのみもあり、アクセスレベルの指定も可能だったります。

    private @Getter @Setter int customerId; //getter setterが生成される。
    private @Setter(AccessLevel.PROTECTED) String customerName; //protectedなsetterが生成される。

ちなみにJPA2.0(eclipselink2.2)を使って対象のエンティティのgetterとかsetterとかを削除してfindとかpersistとかやってみましたが問題ありませんでした。
JPAのエンティティをDDDにおけるエンティティとかバリューオブジェクトに適用する際に可読性上において邪魔くさいsetterとかgetterとかを無くすという使い道もあるかもです。

「別にJPAのエンティティとかツール使って自動生成するし、getterとかsetterとかもIDEから生成するから意味なくね?」とか「アクセサが嫌ならScalaとかRubyやれYO!」という意見は今回は無しの方向でお願いしますw。


最後にリソースの自動開放はこんな感じです。

    @Cleanup FileReader reader=new FileReader("src/main/java/com/mycompany/lomboksample/App.java");
    char buf[]=new char[32];
    while(reader.read(buf)!=-1){
        System.out.print(buf);
    }

ちなみにJava7での新文法はこんな感じ。

    try(FileReader reader=new FileReader("src/main/java/com/mycompany/lomboksample/App.java")){
        char buf[]=new char[32];
        while(reader.read(buf)!=-1){
            System.out.print(buf);
        }
    }

また、@Dataとかつけてるけどgetter自分で定義した場合は当然ながら自分で定義したgetterが呼ばれます。また、@Dataが付いてるクラス内にブレークポイント張ってデバッグかけたら変な所で止まったりしないかなぁとか思いましたが綺麗に止まりました。lombokは結構面白いライブラリーだと思います。

コンパイルとかかけてみたいなぁ〜。とか思ったところで今日は終了します。