Lombok hashCode:: 1.为什么好?2. 为什么没有编译错误?

Ari*_*ria 0 java lombok intellij-lombok-plugin

我有以下简单的Java代码,

import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public class Test{
}
Run Code Online (Sandbox Code Playgroud)

当我查看生成的 deomboked 代码时,我看到以下内容:

public class Test {
    public Test() {
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Test)) {
            return false;
        } else {
            Test other = (Test)o;
            return other.canEqual(this);
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof Test;
    }

    public int hashCode() {
        int result = true;
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白该的实施hashCode()。这是一个好的哈希方法吗?为什么没有编译问题int result = true;?

hashCode()我怀疑这与being有关native,但我不明白为什么我会看到这个实现。


更新:我的主要问题是没有编译错误。例如,如果我添加两个字段,我将有:

import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public class Test{
    private String name;
    public int age;
}

Run Code Online (Sandbox Code Playgroud)

和

...

public int hashCode() {
        int PRIME = true;
        int result = 1;
        int result = result * 59 + this.age;
        Object $name = this.name;
        result = result * 59 + ($name == null ? 43 : $name.hashCode());
        return result;
    }

...
Run Code Online (Sandbox Code Playgroud)

Tho*_*ger 7

您看到的hashCode()这样的方法可能是您用来分析生成的字节码的工具的产物。

在内部,布尔值true和false分别由值 1 和 0 表示。一些字节码反编译器盲目地将 0 转换为 false,将 1 转换为 true - 这就是您的情况似乎发生的情况。

该hashCode()方法应读作

public int hashCode() {
    int result = 1;
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

现在回答问题:

这是一个有效的 hashCode 实现吗?

就是这样。合约equals()规定hashCode(),对于任何两个对象o1,o2当o1.equals(o2)为 true 时,则 也必须为o1.hashCode() == o2.hashCode()。

Lomboks@EqualsAndHashCode注释生成代码,以便具有相同字段值的两个对象被视为相等(因此必须具有相同的 hashCode)。

由于您的类没有任何字段,因此所有实例都被视为相等,因此必须具有相同的 hashCode。hashCode 的实际值并不重要,只要它对于所有实例都是相同的值即可。


您在反编译器中看到的代码是否有错误?

是的,显然是(因为反编译器生成无效的源代码)。

Lombok 本身包含一个集成的“delombok”功能(https://projectlombok.org/features/delombok),该功能为您的第一个测试类创建以下源代码(使用 Lombok 1.18.22):

public class Test {
    @Override
    public boolean equals(final Object o) {
        if (o == this) return true;
        if (!(o instanceof Test)) return false;
        final Test other = (Test) o;
        if (!other.canEqual((Object) this)) return false;
        return true;
    }

    protected boolean canEqual(final Object other) {
        return other instanceof Test;
    }

    @Override
    public int hashCode() {
        final int result = 1;
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)