覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Lombokを用いた開発 (2)

Lombokの利用サンプルです。

Lombokを用いてIDEで開発する場合は基本的にIDEにLombokをインストールしている必要があります。 IDEへのインストールについては以下を参考にしてください


lombok.Builder

Immutableなクラスでfinalのフィールドが増えると引数付きコンストラクタでは、生成処理がコード上不明瞭になる場合があります。
そういった場合の解決策としてBuilderパターンが用いられることがありますが、Builderパターンを利用すると基本的にコードが長くなってしまいます。
これを解決するのが@Builder(lombok.Builder)アノテーションです。
@Value(lombok.Value)アノテーションと組み合わせると強力です。

■@Builderアノテーションを付与したクラス

import lombok.Builder;
import lombok.Value;

@Value
@Builder
public class Person1 {

    private long id;

    private String name;

    private int age;

    private String remarks;
}

■IDEでの表示状態

コード上はメンバしか存在しないにも関わらず、アウトラインにはBuilderクラスが存在しています

f:id:nini_y:20160926222546p:plain

■利用側のコード

コード上は存在しないBuilderクラスを経由して目的のインスタンスを生成することができます。
builderメソッドでBuilder用のクラスを生成し、メンバの値をセットし、最後にbuildメソッドを呼ぶという流れになります。

public class Person1Client {

    public static void main(String[] args) {
        // Builderクラスを経由して各メンバの値を指定してインスタンスを生成
        Person1 p = Person1.builder()
                .id(100L)
                .name("Sample Taro")
                .age(20)
                .remarks("転居回数10回")
                .build();

        System.out.println(p);

        // 引数付きのコンストラクタはパッケージプライベートになっているので
        // 同一パッケージからならアクセスできる
        Person1 p2 = new Person1(100L, "Sample Taro", 20, "sample");
    }
}

■実行結果

Person1(id=100, name=Sample Taro, age=20, remarks=転居回数10回)


Builderクラスの名前やメソッド名を指定することもできます

@Value
@Builder(builderClassName="Builder", builderMethodName="newBuilder", buildMethodName="create")
public class Person2 {

    private long id;

    private String name;

    private int age;

    private String remarks;
}

■利用側のコード

public class Person2Client {

    public static void main(String[] args) {
        Person2.Builder builder = Person2.newBuilder();
        Person2 p = builder
                .id(101L)
                .name("Sample Jiro")
                .age(32)
                .remarks("転居回数3回")
                .create();

        System.out.println(p);
    }
}


lombok.AllArgsConstructor

対象クラスのメンバを全てコンストラクタでセットしたい場合には、@AllArgsConstructorアノテーションを付与することで実現できます

■@AllArgsConstructorアノテーションを付与したクラス

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Person1 {

    private long id;

    private String name;

    private int age;
}

■IDEでの表示状態

全メンバに値をセットするための引数付きコンストラクタが定義されています

f:id:nini_y:20160926222807p:plain

■利用側のコード

コード上は引数付きコンストラクタを記述していませんが、引数付きコンストラクタを呼び出すことができます

public class Person1Client {

    public static void main(String[] args) {
        long id = 5;
        String name = "Sample Hanako";
        int age = 13;
        Person1 p = new Person1(id, name, age);

        System.out.println(p);
    }
}

■実行結果

Person1(id=5, name=Sample Hanako, age=13)


lombok.NoArgsConstructor

対象クラスに明示的にデフォルトコンストラクタを定義したい場合があります。その場合は、@NoArgsConstructorアノテーションを付与します。

■@NoArgsConstructorアノテーションを付与したクラス

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person2 {

    private long id;

    private String name;

    private int age;
}

■IDEでの表示状態

f:id:nini_y:20160926222851p:plain

■利用側のコード

public class Person2Client {

    public static void main(String[] args) {
        long id = 5;
        String name = "Sample Hanako";
        int age = 13;
        Person2 p1 = new Person2(id, name, age);

        System.out.println(p1);


        // デフォルトコンストラクタも定義されている
        Person2 p2 = new Person2();
        p2.setId(6);
        p2.setName("Sample Jiroko");
        p2.setAge(46);

        System.out.println(p2);
    }
}

■実行結果

Person2(id=5, name=Sample Hanako, age=13)
Person2(id=6, name=Sample Jiroko, age=46)


lombok.RequiredArgsConstructor

@Dataや@Valueのアノテーションを使用していない場合にfinalフィールドの値をセットするためのコンストラクタを定義する際は、@RequiredArgsConstructorアノテーションを付与します。

■@RequiredArgsConstructorアノテーションを付与したクラス

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@RequiredArgsConstructor
@ToString
public class Person3 {

    private final long id;

    private final String name;

    private int age;
}

■IDEでの表示状態

f:id:nini_y:20160926222923p:plain

■利用側のコード

public class Person3Client {

    public static void main(String[] args) {
        long id = 5;
        String name = "Godilla Masuo";

        // finalフィールドへの値を設定するための引数付きコンストラクタが定義される
        Person3 p = new Person3(id, name);
        p.setAge(24);

        // finalフィールドへのsetterは定義されない
        // p.setName("Sample Hanako");
        // p.setId(100L);

        System.out.println(p);

        // Person3 p2 = new Person3(); <-- デフォルトコンストラクタは定義されない
    }
}

■実行結果

Person3(id=5, name=Godilla Masuo, age=24)



関連エントリ