在Java的hashCode()String实现中重新排序指令

时间:2015-08-26 02:39:31

标签: java jvm hashcode

我看到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中进行计算 - 禁止这样做?

1 个答案:

答案 0 :(得分:0)

什么禁止这个?

主要是常识,但也是JLS的这些部分(我引用了SE6,但引用应该在不同版本中相当一致)

  

17.4.2行动
  ...
  该规范仅涉及线程间操作。我们不需要关心线程内操作(例如,添加两个局部变量并将结果存储在第三个局部变量中)。如前所述,所有线程都需要遵守Java程序的正确的线程内语义

因此,内存模型遵循JLS的其余部分来定义与局部变量赋值相关的符合行为等。

  

15.26.1简单分配操作员
  ...
  如果左侧操作数表达式是字段访问表达式
  ...评估右手操作数。 ...
  ...由 e.f 表示的变量被赋予如上计算的右手操作数的值。

     

...

     

否则
  ...右侧操作数的值转换为左侧变量的类型...并且转换结果存储在变量

定义字段赋值的符合行为以将右侧表达式分配给字段。

定义变量赋值的符合行为以分配给变量。

根据这些要求,我无法看到如何允许符合要求的实现跳过使用局部变量h