Co oznacza Podwójna tylda ( ~ ~ ) w języku Java?
Przeglądając kod źródłowy Guava, natknąłem się na następujący fragment kodu (część implementacji hashCode
dla klasy wewnętrznej 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;
Zarówno adjust
jak i hash
są int
s. z tego, co wiem o Javie, ~
oznacza bitową negację, więc adjust = ~~adjust
i hash = ~~hash
powinny pozostawić zmienne bez zmian. Uruchamianie małego testu (oczywiście z włączonymi twierdzeniami),
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
assert i == ~~i;
}
Potwierdza to. Zakładając, że faceci z guawy wiedzą, co robią, musi być powód, dla którego to zrobili. Pytanie brzmi: co?
EDIT jak zaznaczono w komentarzach, powyższy test nie uwzględnia przypadku, w którym i
równa się Integer.MAX_VALUE
. Ponieważ {[13] } jest zawsze prawdziwe, będziemy musieli sprawdzić ten przypadek poza pętlą, aby zapobiec zapętleniu go w nieskończoność. Jednak linia
assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE;
Daje ostrzeżenie kompilatora "porównywanie identycznych wyrażeń", które w zasadzie go gwoździuje.
1 answers
W Javie to nic nie znaczy.
Ale ten komentarz mówi, że linia jest specjalnie dla GWT, który jest sposobem kompilacji Javy do JavaScript.
W JavaScript liczby całkowite są jak liczby podwójne, które działają jak liczby całkowite. Mają na przykład wartość max 2^53. Ale operatory bitowe traktują liczby tak, jakby były 32-bitowe, co jest dokładnie tym, czego chcesz w tym kodzie. Innymi słowy, ~~hash
mówi "traktuj hash
jako liczbę 32-bitową" w JavaScript. W szczególności odrzuca wszystkie ale dolne 32 bity (ponieważ operatory bitowe ~
patrzą tylko na dolne 32 bity), co jest identyczne z tym, jak działa przepełnienie Javy.
Jeśli tego nie posiadasz, kod hashowy obiektu będzie różny w zależności od tego, czy jest oceniany w Java-land czy w JavaScript land (poprzez kompilację GWT).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-19 23:12:50