LoginSignup
5
4

More than 5 years have passed since last update.

【Java】Lombokを使ってボイラープレートコード排除

Last updated at Posted at 2018-11-08

お題

Javaでは例えば↓のように、いわゆるJavaBeansを作ると、フィールドの数に応じてけっこうなコード量になる。

public class Book {
    private int id;
    private String name;
    private int price;
    private String publishDate;

    public Book() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getPublishDate() {
        return publishDate;
    }

    public void setPublishDate(String publishDate) {
        this.publishDate = publishDate;
    }

    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                ", publishDate='" + publishDate + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Book book = (Book) o;
        return id == book.id &&
                price == book.price &&
                Objects.equals(name, book.name) &&
                Objects.equals(publishDate, book.publishDate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, price, publishDate);
    }
}

これが、Lombokを使うと、↓のように書くだけで↑と同じメソッドを持つコードになる。

import lombok.Data;

@Data
public class Book {
    private int id;
    private String name;
    private int price;
    private String publishDate;
}

便利なので、少し調べてみることにする。

開発環境

# OS

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="17.10 (Artful Aardvark)"

# Java

$ java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

# IDE

みんな大好きIntelliJ IDEA

実践

導入手順

Mavenプロジェクト生成

mvn -B archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.example -DartifactId=try-java-lombok

pom.xml にLombokを追加

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

IntelliJにLombokプラグイン追加

001.png

Lombokによりどのようなコードになるかを確認するためJarをダウンロード

各アノテーションを試す

全ソースは↓
https://github.com/sky0621/try-java-lombok

@Getter@Setter

その名の通り、変数に付加するとゲッターセッターを自動生成。

【Lombokアノテーション付与ソース】

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class GetterSetter {
    private String text;
}

【実行時のソース】

public class GetterSetter {
    private String text;

    @java.lang.SuppressWarnings("all")
    public String getText() {
        return this.text;
    }

    @java.lang.SuppressWarnings("all")
    public void setText(final String text) {
        this.text = text;
    }
}

@ToString

その名の通り。

【Lombokアノテーション付与ソース】

@lombok.ToString
public class ToString {
    private String text;
}

【実行時のソース】

public class ToString {
    private String text;

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public java.lang.String toString() {
        return "ToString(text=" + this.text + ")";
    }
}

@EqualsAndHashCode

「equals」メソッド及び「hashCode」メソッド生成。

【Lombokアノテーション付与ソース】

@lombok.EqualsAndHashCode
public class EqualsAndHashCode {
    private String text;
}

【実行時のソース】

public class EqualsAndHashCode {
    private String text;

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (!(o instanceof EqualsAndHashCode)) return false;
        final EqualsAndHashCode other = (EqualsAndHashCode) o;
        if (!other.canEqual((java.lang.Object) this)) return false;
        final java.lang.Object this$text = this.text;
        final java.lang.Object other$text = other.text;
        if (this$text == null ? other$text != null : !this$text.equals(other$text)) return false;
        return true;
    }

    @java.lang.SuppressWarnings("all")
    protected boolean canEqual(final java.lang.Object other) {
        return other instanceof EqualsAndHashCode;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final java.lang.Object $text = this.text;
        result = result * PRIME + ($text == null ? 43 : $text.hashCode());
        return result;
    }
}

@NoArgsConstructor

引数なしコンストラクタを生成

【Lombokアノテーション付与ソース】

@lombok.NoArgsConstructor
public class NoArgsConstructor {
}

【実行時のソース】

public class NoArgsConstructor {
    @java.lang.SuppressWarnings("all")
    public NoArgsConstructor() {
    }
}

@AllArgsConstructor

全引数指定コンストラクタを生成

【Lombokアノテーション付与ソース】

@lombok.AllArgsConstructor
public class AllArgsConstructor {
    private int id;
    private String name;
    private Date created;
}

【実行時のソース】

public class AllArgsConstructor {
    private int id;
    private String name;
    private Date created;

    @java.lang.SuppressWarnings("all")
    public AllArgsConstructor(final int id, final String name, final Date created) {
        this.id = id;
        this.name = name;
        this.created = created;
    }
}

@RequiredArgsConstructor

特別な処理が必要なフィールドごとに1つのパラメータを持つコンストラクタを生成

【Lombokアノテーション付与ソース】

@lombok.RequiredArgsConstructor
public class RequiredArgsConstructor {
    @NonNull
    private int id;

    @NonNull
    private String text;

    private Data created;
}

【実行時のソース】

import lombok.Data;
import lombok.NonNull;

public class RequiredArgsConstructor {
    @NonNull
    private int id;
    @NonNull
    private String text;
    private Data created;

    @java.lang.SuppressWarnings("all")
    public RequiredArgsConstructor(@NonNull final int id, @NonNull final String text) {
        if (text == null) {
            throw new java.lang.NullPointerException("text is marked @NonNull but is null");
        }
        this.id = id;
        this.text = text;
    }
}

@Data

上記までで紹介したアノテーションのうち、一挙に@ToString@EqualsAndHashCode@Getterを全フィールドに付与し、@Setterを全てのfinalフィールドに付与。あと、@RequiredArgsConstructorも付与。

【Lombokアノテーション付与ソース】

@lombok.Data
public class Data {
    private int id;
    private String name;
    private int price;
    private String publishDate;
}

【実行時のソース】

public class Data {
    private int id;
    private String name;
    private int price;
    private String publishDate;

    @java.lang.SuppressWarnings("all")
    public Data() {
    }

    @java.lang.SuppressWarnings("all")
    public int getId() {
        return this.id;
    }

    @java.lang.SuppressWarnings("all")
    public String getName() {
        return this.name;
    }

    @java.lang.SuppressWarnings("all")
    public int getPrice() {
        return this.price;
    }

    @java.lang.SuppressWarnings("all")
    public String getPublishDate() {
        return this.publishDate;
    }

    @java.lang.SuppressWarnings("all")
    public void setId(final int id) {
        this.id = id;
    }

    @java.lang.SuppressWarnings("all")
    public void setName(final String name) {
        this.name = name;
    }

    @java.lang.SuppressWarnings("all")
    public void setPrice(final int price) {
        this.price = price;
    }

    @java.lang.SuppressWarnings("all")
    public void setPublishDate(final String publishDate) {
        this.publishDate = publishDate;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (!(o instanceof Data)) return false;
        final Data other = (Data) o;
        if (!other.canEqual((java.lang.Object) this)) return false;
        if (this.getId() != other.getId()) return false;
        final java.lang.Object this$name = this.getName();
        final java.lang.Object other$name = other.getName();
        if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
        if (this.getPrice() != other.getPrice()) return false;
        final java.lang.Object this$publishDate = this.getPublishDate();
        final java.lang.Object other$publishDate = other.getPublishDate();
        if (this$publishDate == null ? other$publishDate != null : !this$publishDate.equals(other$publishDate)) return false;
        return true;
    }

    @java.lang.SuppressWarnings("all")
    protected boolean canEqual(final java.lang.Object other) {
        return other instanceof Data;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        result = result * PRIME + this.getId();
        final java.lang.Object $name = this.getName();
        result = result * PRIME + ($name == null ? 43 : $name.hashCode());
        result = result * PRIME + this.getPrice();
        final java.lang.Object $publishDate = this.getPublishDate();
        result = result * PRIME + ($publishDate == null ? 43 : $publishDate.hashCode());
        return result;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public java.lang.String toString() {
        return "Data(id=" + this.getId() + ", name=" + this.getName() + ", price=" + this.getPrice() + ", publishDate=" + this.getPublishDate() + ")";
    }
}

まとめ

まだまだ便利アノテーションはあるのだけど、今日は時間切れ。
残りは、また後日。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4