1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

lombokで@EqualsAndHashCodeのInclude/Excludeが適用されない

Last updated at Posted at 2023-01-17

問題

lombokでEqualsAndHashCodeを使えば自動的にhashCodeとequalsメソッドを実装してくれる。デフォルトでは、staticではなく、transientでないフィールドはすべて評価の対象となる。特定の対象のみを評価したい場合には、メソッドの前に下記のアノテーションを付ける。

対象コード
@EqualsAndHashCode
public class Data {
  @EqualsAndHashCode.Include
  String key;

  int value;
}

この場合は、keyのみを評価対象とするhashCodeとequalsメソッドができるのを期待する。ネット上に上がっているサンプル例では、このように書いてあるケースもある。しかし、このままでは期待通りに動かない。どうもIncludeが適用されずに、keyもvalueも評価対象になっている。

lombokが生成しているコードを下記コマンドを実施して確認してみる。

lombokの生成コード確認コマンド
java -jar lombok.jar delombok -p {対象のファイル名}.java

先ほどのコードから生成されたコードを確認すると、

lombok生成コード
public class Data {
  String key;
  int value;

  @java.lang.Override
  @java.lang.SuppressWarnings("all")
  public boolean equals(final java.lang.Object o) {
    if (o == this) return true;
    if (!(o instanceof Data)) return false;
    final Data other = (Data) o;
    if (!other.canEqual((java.lang.Object) this)) return false;
    if (this.value != other.value) return false;
    final java.lang.Object this$key = this.key;
    final java.lang.Object other$key = other.key;
    if (this$key == null ? other$key != null : !this$key.equals(other$key)) return false;
    return true;
  }

  @java.lang.SuppressWarnings("all")
  protected boolean canEqual(final java.lang.Object other) {
    return other instanceof Data;
  }

  @java.lang.Override
  @java.lang.SuppressWarnings("all")
  public int hashCode() {
    final int PRIME = 59;
    int result = 1;
    result = result * PRIME + this.value;
    final java.lang.Object $key = this.key;
    result = result * PRIME + ($key == null ? 43 : $key.hashCode());
    return result;
  }
}

やはり、keyもvalueも評価対象となっている。

解決方法

EqualsAndHashCodeアノテーションの変数onlyExplicitlyIncludedをtrueにする。

修正コード
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Data {
  @EqualsAndHashCode.Include
  String key;

  int value;
}

これで期待通り、keyのみが評価されるメソッドが生成される。

修正後のlombok生成コード
public class Data {
  String key;
  int value;

  @java.lang.Override
  @java.lang.SuppressWarnings("all")
  public boolean equals(final java.lang.Object o) {
    if (o == this) return true;
    if (!(o instanceof Data)) return false;
    final Data other = (Data) o;
    if (!other.canEqual((java.lang.Object) this)) return false;
    final java.lang.Object this$key = this.key;
    final java.lang.Object other$key = other.key;
    if (this$key == null ? other$key != null : !this$key.equals(other$key)) return false;
    return true;
  }

  @java.lang.SuppressWarnings("all")
  protected boolean canEqual(final java.lang.Object other) {
    return other instanceof Data;
  }

  @java.lang.Override
  @java.lang.SuppressWarnings("all")
  public int hashCode() {
    final int PRIME = 59;
    int result = 1;
    final java.lang.Object $key = this.key;
    result = result * PRIME + ($key == null ? 43 : $key.hashCode());
    return result;
  }
}

公式サイトをよく見ると、一番最初にちゃんと書いてある。やはり公式をちゃんと読むことが大事。

you can specify exactly which fields or methods you wish to be used by marking them with @EqualsAndHashCode.Include and using @EqualsAndHashCode(onlyExplicitlyIncluded = true).

なお、onlyExplicitlyIncludedという名称だが、EqualsAndHashCode.Includeではなく、特定のフィールドだけ評価から除外するEqualsAndHashCode.Excludeを使用する場合も同じ。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?