Lombok というライブラリを導入すると、Getter/Setter といったよく記述するコードをアノテーションだけで自動生成できます。Google Guava と同様に、Java の冗長なコードを削減する効果があります。簡単な使い方をまとめます。
こちらのページの情報をもとにインストールします。
Eclipse で使用するためには、JAR ファイルをダウンロードしてダブルクリックすることで、GUI インストーラを起動します。Specify location で Eclipse のホームを指定して Install/Update をクリックします。macOS の場合は app 内の ~/bin/Eclipse.app/Contents/Eclipse/
を指定します。インストールが完了すると、eclipse.ini
が更新されて lombok.jar
が Eclipse ホームにコピーされます。
$ diff -u /path/to/eclipse.ini ~/bin/Eclipse.app/Contents/Eclipse/eclipse.ini
--- /path/to/eclipse.ini 2017-04-01 19:33:25.000000000 +0900
+++ /path/to/bin/Eclipse.app/Contents/Eclipse/eclipse.ini 2017-04-01 19:33:51.000000000 +0900
@@ -23,3 +23,4 @@
-Xdock:icon=../Resources/Eclipse.icns
-XstartOnFirstThread
-Dorg.eclipse.swt.internal.carbon.smallFonts
+-javaagent:../Eclipse/lombok.jar
$ ls ~/bin/Eclipse.app/Contents/Eclipse/lombok.jar
後述の Maven, Gradle ビルドツールを利用していない場合、あるいは利用していても Maven, Gradle で管理対象に含めていない場合は、直接 Eclipse の設定を行います。
cp /path/to/lombok.jar /path/to/workspace/myproject/
最新版を、こちらのページを参照して設定します。以下は 2017/04/01 現在の設定内容です。
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.16</version>
<scope>provided</scope>
</dependency>
</dependencies>
compileOnly "org.projectlombok:lombok:1.16.16"
公式ドキュメントを参考にサンプルコードを記載します。
@Getter
および @Setter
MyClass.java
package myproject;
import lombok.Getter;
import lombok.Setter;
import lombok.AccessLevel;
public class MyClass {
@Getter @Setter private boolean employed = true;
@Getter @Setter private int age;
@Setter(AccessLevel.PROTECTED) private String name;
}
Main.java
package myproject;
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.setEmployed(false);
obj.setAge(123);
obj.setName("myname");
System.out.println(obj.isEmployed()); // boolean は `is` です。
System.out.println(obj.getAge()); // int 等は `get` です。
}
}
実行例
false
123
javap コマンドによるクラスファイルの解析
$ javap -private bin/myproject/MyClass.class
Compiled from "MyClass.java"
public class myproject.MyClass {
private boolean employed;
private int age;
private java.lang.String name;
public myproject.MyClass();
public boolean isEmployed();
public void setEmployed(boolean);
public int getAge();
public void setAge(int);
protected void setName(java.lang.String);
}
@NonNull
null が代入された際に NullPointerException
例外を発生させたい場合に利用します。
MyClass.java
package myproject;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
public class MyClass {
@Getter @Setter @NonNull private String myval;
}
Main.java
package myproject;
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.setMyval(null);
System.out.println(obj.getMyval());
}
}
実行例
Exception in thread "main" java.lang.NullPointerException: myval
at myproject.MyClass.setMyval(MyClass.java:8)
at myproject.Main.main(Main.java:7)
@ToString
MyClass.java
package myproject;
import lombok.ToString;
@ToString
public class MyClass {
private String myval1;
private String myval2;
}
Main.java
package myproject;
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
System.out.println(obj.toString());
}
}
実行例
MyClass(myval1=null, myval2=null)
@EqualsAndHashCode
こちらのページに記載したとおり、Java データ型のうち参照型の値の比較は ==
では行えません。参照型のひとつ String 型で実装されている equals()
のように、値を比較するためのメソッドを生成するためには @EqualsAndHashCode
アノテーションを利用します。メンバ変数をもとにハッシュ値を計算する hashCode()
メソッドも定義されます。hashCode が同じであれば equal であると考えます。
MyClass.java
package myproject;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(exclude = "myval3")
public class MyClass {
public String myval1;
public String myval2;
public String myval3;
}
Main.java
package myproject;
public class Main {
public static void main(String[] args) {
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
obj1.myval1 = "xxx";
obj1.myval2 = null;
obj2.myval1 = "xxx";
obj2.myval2 = null;
System.out.println(obj1.equals(obj2));
System.out.println(obj1.hashCode());
System.out.println(obj2.hashCode());
obj1.myval1 = "yyy";
System.out.println(obj1.equals(obj2));
System.out.println(obj1.hashCode());
System.out.println(obj2.hashCode());
}
}
実行例
true
7033964
7033964
false
7092551
7033964
@Data
@Data
アノテーションを適用すると、@Getter
, @Setter
, @EqualsAndHashCode
, @ToString
すべてを適用したのと同じ状況になります。
MyClass.java
package myproject;
import lombok.Data;
@Data
public class MyClass {
public String myval1;
public String myval2;
}
Main.java
package myproject;
public class Main {
public static void main(String[] args) {
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
obj1.setMyval1("xxx");
obj1.setMyval2(null);
obj2.setMyval1("xxx");
obj2.setMyval2(null);
System.out.println(obj1.equals(obj2));
System.out.println(obj1.hashCode());
System.out.println(obj2.hashCode());
obj1.setMyval1("yyy");
System.out.println(obj1.equals(obj2));
System.out.println(obj1.hashCode());
System.out.println(obj2.hashCode());
System.out.println(obj1.toString());
System.out.println(obj2.toString());
}
}
実行例
true
7033964
7033964
false
7092551
7033964
MyClass(myval1=yyy, myval2=null)
MyClass(myval1=xxx, myval2=null)
val
lombok.val
を import すると、Scala における val のような記法が Java で利用できるようになります。再代入が行われないことが保証された定数を、型を省略して定義できます。
Main.java
package myproject;
import lombok.val;
public class Main {
public static void main(String[] args) {
val str = "str";
System.out.println(str);
}
}