"hash" 字符串中的变量 class
"hash" variable in String class
"hash" java.lang.String class 中的私有 "hash" 变量有什么用。它是私有的,每次调用 hashcode 方法时 calculated/re-calculated。
用于缓存String
的hashCode
。因为 String
是不可变的,所以它的 hashCode
永远不会改变,所以在已经计算之后尝试重新计算它是没有意义的。
在您发布的代码中,只有当 hash
的值为 0
时才会重新计算,如果尚未计算 hashCode
则可能会发生这种情况或如果String
的hashCode
实际上是0
,这是可能的!
例如"aardvark polycyclic bitmap"
的hashCode
是0
.
这种疏忽似乎已在 Java 13 中通过引入 hashIsZero
字段得到纠正:
public int hashCode() {
// The hash or hashIsZero fields are subject to a benign data race,
// making it crucial to ensure that any observable result of the
// calculation in this method stays correct under any possible read of
// these fields. Necessary restrictions to allow this to be correct
// without explicit memory fences or similar concurrency primitives is
// that we can ever only write to one of these two fields for a given
// String instance, and that the computation is idempotent and derived
// from immutable state
int h = hash;
if (h == 0 && !hashIsZero) {
h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
if (h == 0) {
hashIsZero = true;
} else {
hash = h;
}
}
return h;
}
"hash" java.lang.String class 中的私有 "hash" 变量有什么用。它是私有的,每次调用 hashcode 方法时 calculated/re-calculated。
用于缓存String
的hashCode
。因为 String
是不可变的,所以它的 hashCode
永远不会改变,所以在已经计算之后尝试重新计算它是没有意义的。
在您发布的代码中,只有当 hash
的值为 0
时才会重新计算,如果尚未计算 hashCode
则可能会发生这种情况或如果String
的hashCode
实际上是0
,这是可能的!
例如"aardvark polycyclic bitmap"
的hashCode
是0
.
这种疏忽似乎已在 Java 13 中通过引入 hashIsZero
字段得到纠正:
public int hashCode() {
// The hash or hashIsZero fields are subject to a benign data race,
// making it crucial to ensure that any observable result of the
// calculation in this method stays correct under any possible read of
// these fields. Necessary restrictions to allow this to be correct
// without explicit memory fences or similar concurrency primitives is
// that we can ever only write to one of these two fields for a given
// String instance, and that the computation is idempotent and derived
// from immutable state
int h = hash;
if (h == 0 && !hashIsZero) {
h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
if (h == 0) {
hashIsZero = true;
} else {
hash = h;
}
}
return h;
}