Java Project Lombok

プロジェクトLombokは、Javaプロジェクトでボイラープレートコードを削減するための非常に便利なツールです。

問題の説明

Java対他言語の議論では、他の言語の支持者から最初に受けるのは、Javaが多くのボイラープレートコードを必要とし、それにうんざりすることはできないということです。同じ問題が複数のプラットフォームや開発者コミュニティで報告されています。ボイラープレートコードを含むコードのサンプルを見てみましょう。

package com.askrakesh.java.manage_boilerplate;

import java.time.LocalDate;

public class Person {

	String firstName;
	String lastName;
	LocalDate dateOfBirth;

	public Person(String firstName, String lastName, LocalDate dateOfBirth) {
		super();
		this.firstName = firstName;
		this.lastName = lastName;
		this.dateOfBirth = dateOfBirth;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public LocalDate getDateOfBirth() {
		return dateOfBirth;
	}

	public void setDateOfBirth(LocalDate dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((dateOfBirth == null) ? 0 : dateOfBirth.hashCode());
		result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
		result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (dateOfBirth == null) {
			if (other.dateOfBirth != null)
				return false;
		} else if (!dateOfBirth.equals(other.dateOfBirth))
			return false;
		if (firstName == null) {
			if (other.firstName != null)
				return false;
		} else if (!firstName.equals(other.firstName))
			return false;
		if (lastName == null) {
			if (other.lastName != null)
				return false;
		} else if (!lastName.equals(other.lastName))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Person [firstName=" + firstName + ", lastName=" + lastName + "dateOfBirth=" + dateOfBirth + "]";
	}

}

A class should have getter-setters for the instance variables, equals & hashCode method implementation, all field constructors and an implementation of toString method. This class so far has no business logic and even without it is 80+ lines of code. This is insane.

プロジェクトLombok

プロジェクトLombokは、Javaライブラリであり、エディターとビルドツールに自動的に組み込まれ、ボイラープレートコードを削減するのに役立ちます。まずはLombokプロジェクトのセットアップ方法を見てみましょう。

JavaプロジェクトLombokはどのように機能しますか?

Lombokには、コンパイル時に処理されるコード内で使用できるさまざまな注釈があり、使用される注釈に基づいて適切なコード拡張が行われます。 Lombokは、コンパイル後にバイトコードがすべてのボイラープレートで注入されるため、ビュータイムでのみコードの削減を行います。 これにより、コードベースを小さく、クリーンで読みやすく、メンテナンスしやすく保つのに役立ちます。

プロジェクトLombok Maven

プロジェクトにLombokを追加するのは簡単です。 Mavenプロジェクトのpom.xmlファイルに以下の依存関係を追加するだけです。

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.16.20</version>
</dependency>

IDE(Eclipse)にLombokプラグインを追加する

Windowsのインストール手順は次のとおりです:

  1. https://projectlombok.org/downloadからjarをダウンロードするか、mavenビルドからダウンロードしたjarを使用します。
  2. ターミナルで次のコマンドを実行します:java -jar lombok.jar
  3. このコマンドは、下の画像に示すようにウィンドウを開きます。 インストーラをインストールして終了し、Eclipseを再起動します。

MacOSの場合は、プロジェクトでLombokを使用する手順は次のとおりです。

  1. lombok.jarをEclipse.app/Contents/MacOSディレクトリにコピーしてください。
  2. Eclipse.app/Contents/Eclipse/eclipse.iniファイルの末尾に-javaagent:lombok.jarを追加してください。
  3. Eclipseを再起動し、以下の画像に示すようにプロジェクトのプロパティで「アノテーション処理」を有効にしてください。

EclipseのアウトラインにおけるLombokの概要

インストール後、どのようにボイラープレートコードが削減されたかを確認しましょう。同じクラスPersonLombokを再作成しました。これは、Lombokの@Getterおよび@Setter アノテーションがfirstNameのインスタンス変数に対して設定された結果です。

JavaバイトコードにおけるLombokの概要

クラスのバイトコードからfirstNameのgetterおよびsetterメソッドの追加を確認できます。

プロジェクトLombokの注釈

プロジェクトLombokは、さまざまなシナリオでボイラープレートコードを削減するのに役立つ多くの注釈を提供しています。いくつか見てみましょう。

  1. コンストラクタの注釈

    @AllArgsConstructor
    public class PersonLombok {
    	@NonNull String firstName;
    	String lastName;
    	LocalDate dateOfBirth;
    	public static void main(String[] args) {
    		new PersonLombok(null, "Kumar", LocalDate.now());
    	}
    }
    

    上記のコードは、クラスに次のものを注入します:

    • @AllArgsConstructorによるすべての引数を持つコンストラクタ
    • @NonNullによるコンストラクタで引数を渡すときのnullチェック。@NonNull注釈は、メソッドのパラメーターとして引数を渡す場合にも使用できます

    こちらがプログラム実行の結果です。 @RequiredArgsConstructorは、特別な処理が必要なフィールドごとに1つのパラメーターを持つコンストラクタを生成します。初期化されていないすべての非初期化最終フィールドにパラメーターが付加され、さらに、@NonNullでマークされたフィールドも、宣言された場所で初期化されていない場合にはパラメーターが付加されます。

  2. Getter/Setter アノテーション

    これらのアノテーションは、フィールドレベルまたはクラスレベルで使用できます。細かい制御が必要な場合は、フィールドレベルで使用します。クラスレベルで使用すると、すべての getter/setter が作成されます。上記で作成したクラスに対して作業を行いましょう。

    @AllArgsConstructor @Getter @Setter
    public class PersonLombok {
    	String firstName;
    	String lastName;
    	LocalDate dateOfBirth;
    }
    
  3. equals、hashCode、toStringのアノテーション

    クラスを作成する際に、hashCode()およびequals()メソッドをオーバーライドすることが推奨されています。Lombokでは、@EqualsAndHashCodeアノテーションが、equals()およびhashCode()メソッドのコードを注入します。さらに、@ToStringアノテーションはtoString()の実装を提供します。これを見てみましょう:

    @AllArgsConstructor @Getter @Setter
    @EqualsAndHashCode 
    @ToString
    public class PersonLombok {
    	String firstName;
    	String lastName;
    	LocalDate dateOfBirth;
    }
    

    Lombokのアノテーションの助けを借りて、ボイラープレートコードなしでPersonクラスを作成しました。しかし、さらに良いことに、上記のクラスで使用されているすべてのアノテーションを@Dataで置き換え、同じ機能を得ることができます。

  4. デザインパターンベースのアノテーション

    @Builderは、ビルダーパターンを使用してクラスをインスタンス化可能にするために必要なコードを自動生成します。

    @Builder
    public class Employee {
    	String firstName;
    	String lastName;
    	LocalDate dateOfBirth;
    
    	public static void main(String[] args) {
    		Employee emp = new EmployeeBuilder().firstName("Rakesh")
    				.lastName("Kumar")
    				.dateOfBirth(LocalDate.now())
    				.build();
    	}
    }
    

    @Delegateは、このアノテーションが使用されているフィールドに対して呼び出しを転送するデリゲートメソッドを生成します。「継承よりもコンポジションを好む」が、これにはアダプターパターンに類似した多くのボイラープレートコードが生成されます。Lombokは、この機能を実装する際に、同じ名前のGroovyのアノテーションからヒントを得ました。実装例を見てみましょう:

    @RequiredArgsConstructor
    public class AdapterImpl implements Adapter {
    	@Delegate
    	private final Adaptee instance;
    
    	public static void main(String[] args) {
    		AdapterImpl impl = new AdapterImpl(new Adaptee());
    		impl.display();
    	}
    }
    
    interface Adapter {
    	public void display();
    }
    
    class Adaptee {
    	public void display() {
    		System.out.println("In Adaptee.display()");
    	}
    }
    

    Lombokは、すべてのアノテーションで細かい制御機能を提供します。

ボイラープレート:Javaアーキテクトは聞いていますか?

はい、そうです。他の言語とは異なり、Javaは言語をアップグレードする際に、旧バージョンのJavaで書かれた既存のコードベースを壊さないように最大限の注意を払っています。これ自体が非常に大きな仕事であり、軽視することはできません。彼らはすでに言語の型推論機能を改善し、構築しており、これが展開されています。ローカル変数の型推論はJava 10に計画されている重要な機能の一つです。この機能はボイラープレートに関するものよりも動的型付けを追加することに関連していますが、ボイラープレートコードを管理するための海の中の小さな一滴です。

要約

ボイラープレートコードを減らすことは、読みやすさを向上させるのに役立ちますし、コードが少ないということはエラーも少ないということを意味します。Project Lombokは、今日、ほとんどの主要な組織で広く使用されています。Lombokから最も有用な機能を提供しました。試してみてください。ソースコード:このチュートリアルで使用されている完全なソースコードをダウンロードするには、私のGithubリンクを訪問してください。

Source:
https://www.digitalocean.com/community/tutorials/java-project-lombok