Lombok hashCode:: 1. 为什么好? 2. 为什么没有编译错误?
Lombok hashCode:: 1. Why good? 2. Why no compile error?
我有以下简单的 Java 代码,
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class Test{
}
当我查看生成的 delmboked 代码时,我看到以下内容:
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;
}
}
我不明白 hashCode()
的实现。这是一种好的哈希方法吗?为什么 int result = true;
没有编译问题?
我怀疑这与 hashCode()
是 native
有关,但我不明白为什么我会看到这个实现。
更新: 我的主要问题是关于缺少编译错误。例如,如果我添加两个字段,我将有:
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class Test{
private String name;
public int age;
}
和
...
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;
}
...
我认为这是因为您的 Test
class 没有任何字段。因此,在使用 @EqualsAndHashCode
时,class 的所有实例都将被视为“相等”。所以 delmboked 实施反映了这一点。
您看到这样的 hashCode()
方法可能是您用来分析生成的字节码的工具的产物。
在内部,布尔值 true
和 false
分别由值 1 和 0 表示。一些字节码反编译器盲目地将 0 翻译成 false 并将 1 翻译成 true - 这似乎是你的情况。
hashCode()
方法应读作
public int hashCode() {
int result = 1;
return 1;
}
现在回答问题:
这是一个有效的 hashCode 实现吗?
当然是。 equals()
和 hashCode()
的契约声明对于任何两个对象 o1
和 o2
当 o1.equals(o2)
为真时它也必须是 o1.hashCode() == o2.hashCode()
.
Lomboks @EqualsAndHashCode
注释生成代码,使具有相同字段值的两个对象被视为相等(因此必须具有相同的 hashCode)。
由于您的 class 没有任何字段,所有 实例被认为是相等的,因此必须具有相同的 hashCode。 hashCode 的实际值并不重要,只要它对所有实例都是相同的值即可。
您在反编译器中看到的代码是否有错误?
是的,显然是(因为反编译器生成了无效的源代码)。
Lombok 本身包含一个集成的“delombok”功能 (https://projectlombok.org/features/delombok),该功能会为您的第一个测试创建 class 以下源代码(使用 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;
}
}
我有以下简单的 Java 代码,
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class Test{
}
当我查看生成的 delmboked 代码时,我看到以下内容:
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;
}
}
我不明白 hashCode()
的实现。这是一种好的哈希方法吗?为什么 int result = true;
没有编译问题?
我怀疑这与 hashCode()
是 native
有关,但我不明白为什么我会看到这个实现。
更新: 我的主要问题是关于缺少编译错误。例如,如果我添加两个字段,我将有:
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class Test{
private String name;
public int age;
}
和
...
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;
}
...
我认为这是因为您的 Test
class 没有任何字段。因此,在使用 @EqualsAndHashCode
时,class 的所有实例都将被视为“相等”。所以 delmboked 实施反映了这一点。
您看到这样的 hashCode()
方法可能是您用来分析生成的字节码的工具的产物。
在内部,布尔值 true
和 false
分别由值 1 和 0 表示。一些字节码反编译器盲目地将 0 翻译成 false 并将 1 翻译成 true - 这似乎是你的情况。
hashCode()
方法应读作
public int hashCode() {
int result = 1;
return 1;
}
现在回答问题:
这是一个有效的 hashCode 实现吗?
当然是。 equals()
和 hashCode()
的契约声明对于任何两个对象 o1
和 o2
当 o1.equals(o2)
为真时它也必须是 o1.hashCode() == o2.hashCode()
.
Lomboks @EqualsAndHashCode
注释生成代码,使具有相同字段值的两个对象被视为相等(因此必须具有相同的 hashCode)。
由于您的 class 没有任何字段,所有 实例被认为是相等的,因此必须具有相同的 hashCode。 hashCode 的实际值并不重要,只要它对所有实例都是相同的值即可。
您在反编译器中看到的代码是否有错误?
是的,显然是(因为反编译器生成了无效的源代码)。
Lombok 本身包含一个集成的“delombok”功能 (https://projectlombok.org/features/delombok),该功能会为您的第一个测试创建 class 以下源代码(使用 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;
}
}