Hal*_*ast 192 java gwt bit-manipulation bitwise-operators
在浏览Guava的源代码时,我遇到了以下一段代码(hashCode
内部类的实现的一部分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;
Run Code Online (Sandbox Code Playgroud)
两者的adjust
和hash
是int
秒.从我所知道的关于Java,~
意味着位求反,所以adjust = ~~adjust
并hash = ~~hash
应离开变量不变.运行小测试(当然启用断言),
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
assert i == ~~i;
}
Run Code Online (Sandbox Code Playgroud)
证实了这一点.假设Guava家伙知道他们在做什么,他们必须有理由这样做.问题是什么?
编辑正如评论中指出的,上述测试不包括i
等于的情况Integer.MAX_VALUE
.由于i <= Integer.MAX_VALUE
总是如此,我们需要在循环外检查这种情况,以防止它永远循环.但是,行
assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE;
Run Code Online (Sandbox Code Playgroud)
产生编译器警告"比较相同的表达式",它几乎指出了它.
ysh*_*vit 244
在Java中,它没有任何意义.
但该评论说该行专门用于GWT,这是一种将Java编译为JavaScript的方法.
在JavaScript中,整数有点像双打 - 即整数.例如,它们的最大值为2 ^ 53.但是按位运算符将数字视为32位,这正是您在此代码中所需的.换句话说,在JavaScript中~~hash
说" hash
视为32位数".具体来说,它会丢弃除最后32位之外的所有位(因为按位运算~
符仅查看底部的32位),这与Java的溢出工作方式相同.
如果你没有这个,那么对象的哈希码会有所不同,这取决于它是在Java-land还是在JavaScript域中进行评估(通过GWT编译).
归档时间: |
|
查看次数: |
17295 次 |
最近记录: |