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

时间:2015-04-19 23:08:24

标签: java gwt bit-manipulation bitwise-operators

在浏览Guava的源代码时,我遇到了以下代码(内部类hashCode的{​​{1}}实现的一部分):

CartesianSet

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; adjust都是hash。根据我对Java的了解,int表示按位否定,因此~adjust = ~~adjust应保持变量不变。运行小测试(当然启用了断言),

hash = ~~hash

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

编辑正如评论中所指出的,上述测试并未包括for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) { assert i == ~~i; } 等于i的情况。由于Integer.MAX_VALUE始终为真,我们需要在循环外检查该情况以防止它永远循环。但是,行

i <= Integer.MAX_VALUE

产生编译器警告&#34;比较相同的表达式&#34;,它几乎指出它。

1 个答案:

答案 0 :(得分:240)

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

但该评论说该专线专门针对GWT,这是一种将Java编译为JavaScript的方法。

在JavaScript中,整数有点像双打 - 就像整数一样。例如,它们的最大值为2 ^ 53。但bitwise operators将数字视为32位,这正是您在此代码中所需要的。换句话说,~~hash表示&#34;将hash视为32位数字&#34;在JavaScript中。具体来说,它会丢弃除最后32位之外的所有位(因为按位~运算符只查看底部的32位),这与Java溢出的工作方式相同。

如果你没有这个,那么对象的哈希码会有所不同,这取决于它是在Java-land还是在JavaScript中评估(通过GWT编译)。