【发布时间】:2020-12-13 12:45:11
【问题描述】:
直到最近,我才发现空的String 的哈希码为零。这让我很吃惊,因为null 通常分配的哈希码为零,例如Objects.hashCode(Object) 和ArrayList.hashCode()。
这是String.hashCode() 的 JDK 11 source code:
/** Cache the hash code for the string */
private int hash; // Default to 0
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
hash = h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
}
return h;
}
想法:一个空的String 可以有一个哈希码,因为这将匹配空数组的Arrays.hashCode(Object[])。或者,可以使用任何其他硬编码的非零值,类似于serialVersionUID。目的是与null 区分开来。如果这个想法有缺陷(除了向后兼容性问题),请解释原因。
我找到了解决该问题的其他问题/答案...但没有一个确切的答案:
【问题讨论】:
-
甚至没有任何向后兼容性问题,因为
hashCode被明确允许在同一应用程序的运行之间进行更改。这是为了防止哈希冲突攻击。 -
@Thomas 但是,
String#hashCode()is specified 的行为。 -
如果你问为什么选择这个,你必须问他们。如果您询问是否有人依赖这种行为,您必须检查是否编写过 Java 代码(这似乎不太可能,因为所有哈希值为零都意味着字符串的哈希值为零)。
-
hashCode 不能返回 null,因为 int 不能为 null。
-
“我想知道是否有人真的依赖这种行为?” - 这无法回答。尤其是因为有些人可能在不知不觉中依赖它。