我看到了一个地段 的 帖子,它讨论了为什么Java当前实现String的hashCode()方法是正确的:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i]; // (*)
}
hash = h; // (**)
}
return h;
}但是,上述解释的重点是读取hash字段的值,以及如果不使用局部变量h,指令重新排序可能会引起问题。
我的问题是:内存模型禁止编译器或JVM在(**)行之前向hash写入临时结果
例如,假设的编译器/JVM可能决定“保存局部变量”,并将计算(*)不是在局部变量h中,而是直接在hash - what中执行。
发布于 2015-08-26 05:00:36
什么禁止这样做?
主要是常识,但也包括JLS的这些部分(我引用的是SE6,但引用应该在不同版本之间相当一致)
17.4.2行动 ..。 本规范只涉及线程间操作.我们不需要关注线程内的操作(例如,添加两个局部变量并将结果存储在第三个局部变量中)。如前所述,所有线程都需要遵守Java程序正确的线程内部语义。
因此,内存模型符合JLS的其余部分,用于定义与分配局部变量有关的符合行为,等等。
15.26.1简单赋值算子 ..。 如果左操作数表达式是字段访问表达式,则为 ..。计算右手操作数。..。 ..。用e.f表示的变量被指定为上面计算的右手操作数的值。 ..。否则 ..。右操作数的值被转换为左手变量的类型.转换的结果被存储到变量中。
字段分配的一致性行为被定义为将右表达式分配给字段。
变量赋值的一致性行为被定义为将变量赋值。
基于这些需求,我看不出如何允许符合的实现跳过局部变量h的使用。
https://stackoverflow.com/questions/32217128
复制相似问题