※このページではアフィリエイト広告を紹介しています

Javaの定型コードを自動生成する ~lombok~

Java
この記事は約7分で読めます。

この記事の目的

「コンストラクタ」、「ゲッター」、「セッター」など、Javaのプログラムを書く上で繰り返し記述する定型コードがいくつかあります。これらの定型コードを自動で生成してくれるライブラリlombokを紹介します。執筆時点の最新版は1.18.20です。

GitHub - projectlombok/lombok: Very spicy additions to the Java programming language.
Very spicy additions to the Java programming language. - projectlombok/lombok

Humanクラスを作成

Humanクラス

「名前」、「生年月日」、「年齢」の3つのフィールドを持つHumanクラスを作成することを考えます。これら3つのフィールドはインスタンス生成時の値から変更できないことにすると、下記のように書くことができます。

import java.time.LocalDate;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public class Human {
	private final String name;
	private final LocalDate birthDate;
	private final int age;
}

Eclipseのアウトラインを見ることで、Humanクラスの概要を確認することができます。lombokによって下記のコンストラクタやメソッドが自動生成されます。

  • 全フィールドを引数とするコンストラクタ : @AllArgsConstructor
  • 全フィールドのゲッター : @Getter

インスタンス生成時のフィールド値から値を変更できないクラスを作成するときは、「@Value」も便利です。

import java.time.LocalDate;

import lombok.Value;

@Value
public class Human {
	private final String name;
	private final LocalDate birthDate;
	private final int age;
}

「全フィールドを引数とするコンストラクタ」と「全フィールドのゲッター」に加え、下記も生成されます。

  • Humanクラスのインスタンスが等しいかを判定するequalsメソッド
  • Humanクラスのハッシュ値(インスタンスが等しいかを手軽に判定するために使用)を計算するhashCodeメソッド
  • Humanクラスのもつ情報を文字列化するtoStringメソッド

Humanクラスを使ってみる

Humanクラスはシンプルで使いやすいですが、生年月日と年齢に矛盾する値を設定できる難点があります。2000年生まれのTaroさんは2021年現在21歳のはずですが、30歳にすることができます。

import java.time.LocalDate;

public class HumanMain {

	public static void main(String[] args) {
		Human taro = new Human("Taro", LocalDate.of(2000, 1, 1), 30);
		System.out.println(taro.getName());
		System.out.println(taro.getBirthDate());
		System.out.println(taro.getAge());
	}

}
Taro
2000-01-01
30

Humanクラスをより便利に

UsefulHumanクラス

Humanクラスの不便な点を改善したUsefulHumanクラスが下記です。

import java.time.LocalDate;
import java.time.Period;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public class UsefulHuman {
	private final String name;
	private final LocalDate birthDate;
	private final int age;

	public static UsefulHuman create(String name, LocalDate birthDate) {
		return new UsefulHuman(name, birthDate, calculateAge(birthDate));
	}

	private static int calculateAge(LocalDate birthDate) {
		// 生年月日と現在日付の間の年数を返す
		return Period.between(birthDate, LocalDate.now()).getYears();
	}
}

Humanクラスとの違いは下記です。@AllArgsConstructorのアクセスレベルを変更する機能を利用しています。

  • 全フィールドを引数とするprivateのコンストラクタ : @AllArgsConstructor(access = AccessLevel.PRIVATE)
  • コンストラクタの代わりにUsefulHumanクラスのインスタンスを返すcreateメソッド
  • 生年月日から年齢を計算するcalculateAgeメソッド

EclipseのアウトラインでUsefulHumanクラスの概要を確認することができ、上記の違いが反映されていることが分かります。

int ageをフィールドにもたないようにすることも考えられます。この場合、getAgeメソッドが呼ばれる度に生年月日から年齢を計算して返します。

import java.time.LocalDate;
import java.time.Period;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public class UsefulHuman {
	private final String name;
	private final LocalDate birthDate;

	public int getAge() {
		// 生年月日と現在日付の間の年数を返す
		return Period.between(birthDate, LocalDate.now()).getYears();
	}
}

UsefulHumanクラスを使ってみる

UsefulHumanのインスタンス時にint ageを渡す必要がなくなってより使いやすくなった上に、正しい年齢「21歳」も取得できています。

import java.time.LocalDate;

public class UsefulHumanMain {

	public static void main(String[] args) {
		UsefulHuman taro = 
				UsefulHuman.create("Taro", LocalDate.of(2000, 1, 1));
		System.out.println(taro.getName());
		System.out.println(taro.getBirthDate());
		System.out.println(taro.getAge());
	}

}
Taro
2000-01-01
21

まとめ

ライブラリlombokを使うことで定型コードを書く手間から解放され、より使いやすいプログラムを書くことに集中できることが分かりました。

コメント

タイトルとURLをコピーしました