我看到lot of posts讨论了为什么Java当前concat(Head, blob1, Mid, blob2, Mid, blob3, Tail)
hashCode()
方法的实现是正确的:
String
然而,上述解释集中于读取 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
,指令重新排序可能会导致问题。
我的问题是: Java内存模型中的内容禁止编译器或JVM在行h
之前将临时结果写入hash
?
例如,假设的编译器/ JVM可能决定“保存局部变量”并且不在局部变量(**)
中进行计算(*)
,而是直接在h
中进行计算 - 禁止这样做?
答案 0 :(得分:0)
什么禁止这个?
主要是常识,但也是JLS的这些部分(我引用了SE6,但引用应该在不同版本中相当一致)
17.4.2行动
...
该规范仅涉及线程间操作。我们不需要关心线程内操作(例如,添加两个局部变量并将结果存储在第三个局部变量中)。如前所述,所有线程都需要遵守Java程序的正确的线程内语义
因此,内存模型遵循JLS的其余部分来定义与局部变量赋值相关的符合行为等。
15.26.1简单分配操作员
...
如果左侧操作数表达式是字段访问表达式
...评估右手操作数。 ...
...由 e.f 表示的变量被赋予如上计算的右手操作数的值。...
否则
中
...右侧操作数的值转换为左侧变量的类型...并且转换结果存储在变量
定义字段赋值的符合行为以将右侧表达式分配给字段。
定义变量赋值的符合行为以分配给变量。
根据这些要求,我无法看到如何允许符合要求的实现跳过使用局部变量h
。