LoginSignup
1
2

More than 5 years have passed since last update.

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

Posted at

お題

前回の続きで、Lombokによるボイラープレート機能の紹介。

開発環境

# 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

実践

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

@Builder

Builderパターンのソースを生成

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

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

【実行時のソース】

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

    @java.lang.SuppressWarnings("all")
    Builder(final int id, final String name, final int price, final String publishDate) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.publishDate = publishDate;
    }


    @java.lang.SuppressWarnings("all")
    public static class BuilderBuilder {
        @java.lang.SuppressWarnings("all")
        private int id;
        @java.lang.SuppressWarnings("all")
        private String name;
        @java.lang.SuppressWarnings("all")
        private int price;
        @java.lang.SuppressWarnings("all")
        private String publishDate;

        @java.lang.SuppressWarnings("all")
        BuilderBuilder() {
        }

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

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

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

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

        @java.lang.SuppressWarnings("all")
        public Builder build() {
            return new Builder(id, name, price, publishDate);
        }

        @java.lang.Override
        @java.lang.SuppressWarnings("all")
        public java.lang.String toString() {
            return "Builder.BuilderBuilder(id=" + this.id + ", name=" + this.name + ", price=" + this.price + ", publishDate=" + this.publishDate + ")";
        }
    }

    @java.lang.SuppressWarnings("all")
    public static BuilderBuilder builder() {
        return new BuilderBuilder();
    }
}

【使い方】

public class Main {
    public static void main(String... args){
        System.out.println(
                Builder.builder()
                        .id(100)
                        .name("名前")
                        .price(937)
                        .publishDate("2018-11-09")
                        .build().toString());
    }
}

@Value

不変クラスを生成

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

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

【実行時のソース】

public final class Value {
    private final int id;
    private final String name;
    private final int price;
    private final String publishDate;

    @java.lang.SuppressWarnings("all")
    public Value(final int id, final String name, final int price, final String publishDate) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.publishDate = publishDate;
    }

    @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.Override
    @java.lang.SuppressWarnings("all")
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (!(o instanceof Value)) return false;
        final Value other = (Value) o;
        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.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 "Value(id=" + this.getId() + ", name=" + this.getName() + ", price=" + this.getPrice() + ", publishDate=" + this.getPublishDate() + ")";
    }
}

@Cleanup

ファイルオープンなど、処理後のクローズロジックを付加してくれる。
が、Java7以降ならtry-with-resourcesを使うべきなので、使うとしたらJava6までかな。

public class Cleanup {
    public static void main(String[] args) throws IOException {
        @lombok.Cleanup InputStream in = new FileInputStream(args[0]);
        @lombok.Cleanup OutputStream out = new FileOutputStream(args[1]);
        byte[] b = new byte[10000];
        while (true) {
            int r = in.read(b);
            if (r == -1) break;
            out.write(b, 0, r);
        }
    }
}
import java.io.*;

public class Cleanup {
    public static void main(String[] args) throws IOException {
        InputStream in = new FileInputStream(args[0]);
        try {
            OutputStream out = new FileOutputStream(args[1]);
            try {
                byte[] b = new byte[10000];
                while (true) {
                    int r = in.read(b);
                    if (r == -1) break;
                    out.write(b, 0, r);
                }
            } finally {
                if (java.util.Collections.singletonList(out).get(0) != null) {
                    out.close();
                }
            }
        } finally {
            if (java.util.Collections.singletonList(in).get(0) != null) {
                in.close();
            }
        }
    }
}

@Log (java.util.logger.Logger)

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

@lombok.extern.java.Log
public class LogExample {
    public static void main(String... args) {
        log.severe("Something's wrong here");
    }
}

【実行時のソース】

public class LogExample {
    @java.lang.SuppressWarnings("all")
    private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());

    public static void main(String... args) {
        log.severe("Something\'s wrong here");
    }
}

@NonNull

メソッド引数のnullチェック挿入。
ただし、デフォルトはNullPointerExceptionがスローされる。
IllegalArgumentExceptionに変えることは可能。

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

public class NonNull {
    private int id;
    @lombok.NonNull
    private String name;

    public void setNonNull(@lombok.NonNull Book book) {
        this.name = book.getName();
    }
}

【実行時のソース】

public class NonNull {
    private int id;
    @lombok.NonNull
    private String name;

    public void setNonNull(@lombok.NonNull Book book) {
        if (book == null) {
            throw new java.lang.NullPointerException("book is marked @NonNull but is null");
        }
        this.name = book.getName();
    }
}

まとめ

ひとまず基本的な機能のいくつかをピックアップして紹介した。ちなみに本家は↓
https://projectlombok.org/features/all

その他、実験的な機能が下記に紹介されている。
https://projectlombok.org/features/experimental/all

1
2
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
1
2