java recherche - Quelle est la signification du double tilde (~~) en Java?




1 Answers

En Java, cela ne veut rien dire.

Mais ce commentaire dit que la ligne est spécifiquement pour GWT, qui est un moyen de compiler Java en JavaScript.

En JavaScript, les entiers sont un peu comme des doubles-que-agir-comme-entiers. Ils ont une valeur maximale de 2 ^ 53, par exemple. Mais les opérateurs bit à bit traitent les nombres comme s'ils étaient en 32 bits, ce qui est exactement ce que vous voulez dans ce code. En d'autres termes, ~~hash dit "traiter le hash comme un nombre de 32 bits" en JavaScript. Plus précisément, il rejette tout sauf les 32 bits inférieurs (puisque les opérateurs bitwise ~ ne regarde que les 32 bits inférieurs), ce qui est identique au fonctionnement du débordement de Java.

Si vous ne l'aviez pas, le code de hachage de l'objet serait différent selon qu'il est évalué en Java-land ou en JavaScript (via une compilation GWT).

bibliographique exemple

En parcourant le code source de Guava, je suis tombé sur le morceau de code suivant (partie de l'implémentation de hashCode pour la classe interne 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;

Les deux d' adjust et de hash sont int s. D'après ce que je sais de Java, ~ signifie une négation au niveau des bits, donc adjust = ~~adjust et hash = ~~hash devrait laisser les variables inchangées. Exécuter le petit test (avec des assertions activées, bien sûr),

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

confirme cela. En supposant que les gars de la goyave sachent ce qu'ils font, il doit y avoir une raison pour qu'ils le fassent. La question est quoi?

EDIT Comme indiqué dans les commentaires, le test ci-dessus n'inclut pas le cas où i est égal à Integer.MAX_VALUE . Puisque i <= Integer.MAX_VALUE est toujours vrai, nous devrons vérifier ce cas en dehors de la boucle pour l'empêcher de boucler pour toujours. Cependant, la ligne

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

donne l'avertissement du compilateur "Comparant des expressions identiques", ce qui le cloue à peu près.




Related