Java中的double tilde(~~)是什么意思?

当浏览Guava的源代码时,我遇到了以下一段代码(用于内部类CartesianSethashCode实现的一部分):

 int adjust = size() - 1; for (int i = 0; i < axes.size(); i++) { adjust *= 31; adjust = ~~adjust; // in GWT, we have to deal with integer overflow carefully } int hash = 1; for (Set<E> axis : axes) { hash = 31 * hash + (size() / axis.size() * axis.hashCode()); hash = ~~hash; } hash += adjust; return ~~hash; 

adjusthash都是int 。 从我所了解的Java中, ~意味着按位否定,所以adjust = ~~adjusthash = ~~hash应该使variables保持不变。 运行小testing(当然,启用断言),

 for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) { assert i == ~~i; } 

证实了这一点。 假设番石榴家伙知道他们在做什么,他们必须有一个这样做的理由。 问题是什么?

编辑正如在评论中指出的,上面的testing不包括i等于Integer.MAX_VALUE的情况。 由于i <= Integer.MAX_VALUE总是为真,因此我们需要检查循环外部的情况,以防止它永远循环。 但是,行

 assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE; 

产生编译器警告“比较相同的expression式”,这几乎是钉钉子。

在Java中,它没有任何意义。

但是那个评论说这条线专门用于GWT,这是一种将Java编译成JavaScript的方法。

在JavaScript中,整数有点像双精度,整数。 例如,它们的最大值为2 ^ 53。 但是按位运算符将数字视为32位,这正是您在此代码中想要的。 换句话说,在~~hash~~hash表示“将hash视为32位数”。 具体地说,它丢弃除底部32位以外的所有数据(因为位运算符只能查看最低32位),这与Java溢出的工作方式相同。

如果你没有这个,那么对象的哈希代码会根据是在Java-land还是在JavaScript land(通过GWT编译)进行评估而有所不同。