JavaでAndroid開発をするなら絶対に導入したいLombok - 超戦士が秘めたる13のパワー[劇場版]

#val - 型推論的なもの

[Finally! Hassle-free final local variables.](http://projectlombok.org/features/val.html)

本来であれば

```java:
final ArrayList<String> example = new ArrayList<String>();
example.add("Hello, World!");
```

と書かなければならない所を、右辺でArrayList作って左辺に入れてるんだから、左辺もそりゃArrayListだろ、と推測してくれて

```java
val example = new ArrayList<String>();
example.add("Hello, World!");
```

と書ける。

らしいのだが「高機能過ぎて怖い」「Javaの教義に反し過ぎてるのでは」といった意見、[「valを使うとコマンドラインでのコンパイルが不思議な力で死ぬ事になる」](http://d.hatena.ne.jp/xuwei/20130823/1377231525)といった風の噂などを考慮して、今やっているPJでは導入は見送っている。

#@NonNull - Nullチェック処理の生成

[or: How I learned to stop worrying and love the NullPointerException.](http://projectlombok.org/features/NonNull.html)

```java
public Example(Person person) {
  super("Hello");
  if (person == null) {
    throw new NullPointerException("person");
  }
  this.name = person.getName();
}
```

Nullチェック職人が丹精込めて毎朝書いていた処理が

```java
public Example(@NonNull Person person) {
  super("Hello");
  this.name = person.getName();
}
```

@NonNullアノテーションをつけるだけでよくなる。デフォルトはNullPointerExceptionだが、[設定(lombok.config)](http://projectlombok.org/features/configuration.html)でIllegalArgumentExceptionに変更する事も出来るらしい。

#@Cleanup - 終了時クリーンアップ処理の生成

[Automatic resource management: Call your close() methods safely with no hassle.](http://projectlombok.org/features/Cleanup.html)

```java 
@Cleanup InputStream in = new FileInputStream("hoge");
```

と書くとスコープ脱出時に自動で

```java 
in.close()
```

を呼んでくれるようになる。もちろんクリーンアップ処理がcloseという名前だとは限らないので、その場合は

```java 
@Cleanup("dispose") InputStream in = new FileInputStream("hoge");
```

と書けばcloseではなくdisposeメソッドを呼んでくれるようになる。

#@Getter and @Setter - アクセサ生成

[Never write public int getFoo() {return foo;} again.](http://projectlombok.org/features/GetterSetter.html)

```java
@Getter @Setter private int age = 10;
```

とか

```java
@Setter(AccessLevel.PROTECTED) private String name;
```

みたいに書けばgetterとかsetterを自動生成してくれる。恐らくLombokの中で最も導入コスパが良く最も有名な機能。マジカル度も低いので安心感がある。Objective-Cにおける@propertyみたいなもの。

コードサイズ削減に威力を発揮し、コードレビュやコード修正時にコードを読む者の心の健康を保つのに役立つ。(書く方はIDEによるgetter/setterコード生成と大して変わらない)デメリットとして[「フィールド名変更が少し面倒」](http://d.hatena.ne.jp/nowokay/20130730)という話もあるが、AndroidStudio0.6.1+LombokPlugin0.8.6の環境においてはRefactorからRenameすれば綺麗にアクセサ呼び出し部分までリネームしてくれた。かしこい。

なお、色々と設定可能項目がある

* メソッドチェーンとか[FluentInterface](http://en.wikipedia.org/wiki/Fluent_interface#Java)したい時用の設定(デフォルト無効)
* [フィールド名にmとかsとか付けたい場合](http://source.android.com/source/code-style.html#follow-field-naming-conventions)のプレフィックス設定(デフォルト無効)
* boolean型のgetterの場合はgetHogeではなくisHogeという名前でメソッドを生成するけど別にいいよね設定(デフォルトはisHogeになる)

#@ToString - Pretty-Print

[No need to start a debugger to see your fields: Just let lombok generate a toString for you!](http://projectlombok.org/features/ToString.html)

クラスの頭に付けておくとtoString時にオブジェクトを見やすい形式で出力してくれる。PHPにおけるvar_dumpとかRubyにおけるppとかそういうの。Rubyよくしらないけど。

#@EqualsAndHashCode - equalsメソッドとhashCodeメソッドのオーバーライド
[Equality made easy: Generates hashCode and equals implementations from the fields of your object.](http://projectlombok.org/features/EqualsAndHashCode.html)

クラスの頭に付けておくとそのクラスのequalsメソッドとhashCodeメソッドをオーバーライドしてくれる。具体的にどういうロジックのequals/hashCodeになるのかはリンク先を参照。同一性比較時に対象外としたいフィールドがあれば

```java
@EqualsAndHashCode(exclude={"id", "shape"})
```

のように指定すればよい。

#@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor - コンストラクタの生成

[Constructors made to order: Generates constructors that take no arguments, one argument per final / non-null field, or one argument for every field.](http://projectlombok.org/features/Constructor.html)

アノテーション名まま。@NoArgsConstructorをクラスの頭に付ければ引数なしコンストラクタを、@RequiredArgsConstructorなら必須パラメータぽいもの(@NonNullなフィールドとか)を引数として受け取るコンストラクタを、@AllArgsConstructorなら全てのフィールドを引数として受け取るコンストラクタを、それぞれ生成する。

```java
@RequiredArgsConstructor(staticName="of")
```

みたいに書けばstaticなfactoryメソッドを生成してくれてMapEntry.of("foo", 5)みたいに呼べる。(java.util.EnumSetのofみたいな?)

#@Data - @ToString+@EqualsAndHashCode+@Getter/@Setter+@RequiredArgsConstructor

[All together now: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, @Setter on all non-final fields, and @RequiredArgsConstructor!](http://projectlombok.org/features/Data.html)

上記で紹介してきたアノテーションを一行で呼び出せるショートカット。必要に応じて個別のアノテーションで@dataを上書きが可能。ここまで高機能(ジェネレートされる量が多い)になると導入の心理的ハードルはちょっと高い。

#@Value - @Dataのイミュータブル版的な
[Immutable classes made very easy.](http://projectlombok.org/features/Value.html)
@Dataと同じく高機能。特徴は

* オブジェクト生成時にコンストラクタで値を受け取りフィールドに設定する
* getterは生成されるが、setterは生成されない
* フィールドにはデフォルトでfinal修飾子がつく

いわゆるValueObject

#@SneakyThrows - チェック例外の無視

[To boldly throw checked exceptions where no one has thrown them before!](http://projectlombok.org/features/SneakyThrows.html)

この秘められた力の封印は無闇に解いてはならない。選ばれし戦士だけがその剣を抜くがいい。

#@Synchronized - メソッドの排他制御

[synchronized done right: Don't expose your locks.](http://projectlombok.org/features/Synchronized.html)

メソッドの頭に@Synchronizedを付けると、ロックオブジェクトを用意して排他制御してくれる。

#@Getter(lazy=true) - getter値のキャッシュ
[Laziness is a virtue!](http://projectlombok.org/features/GetterLazy.html)

コストの高い処理の結果をキャッシュして、キャッシュがあればキャッシュを返してくれるぜイエイ。しかもthread-safeだぜやったー。でも、Lombokを使ってでも実現したいぐらい頻繁にこれを書く事ある？世の中にはあるかもしれない。

#@Log (and friends) - logger生成
[Captain's Log, stardate 24435.7: "What was that line again?"](http://projectlombok.org/features/GetterLazy.html)

選べる6種類のlogger。@Logならjava.util.logging.Loggerが、@Log4jならorg.apache.log4j.Loggerが、logという名前(設定で変更可能)のフィールドで準備される。

#14番目の力

というわけでアクセサの自動生成だけに留まらないLombokのパワーを13個紹介してきましたが、[experimental features](http://projectlombok.org/features/experimental/index.html)には、delegateの繋ぎこみ部分を生成してくれる[@Delegate](http://projectlombok.org/features/experimental/Delegate.html)、[Builderパターン](http://d.hatena.ne.jp/gakuzo/20090708/1247062344)用のビルダーをインナークラスで生成しくれる[@Builder](http://projectlombok.org/features/experimental/Builder.html)、冒涜的な使用例が載っていて怖い[@ExtensionMethod](http://projectlombok.org/features/experimental/ExtensionMethod.html)など、魅力的な機能がまだまだ控えているので、用法用量を守ってExperimental because:の部分をちゃんと読んだ上でガンガン服用し、異常が見られた場合には速やかに服用を止め医師の診断を受けましょう。

Lombokの機能全般に言えることですが、メタプロと同様のメリット/デメリットがあるのではないかと個人的には思います。また一部手元で動作確認を行っていない機能もあるため、ご自身でご確認の上ご利用ください。