Exemple code:La façon la plus élégante pour convertir un octet à un int en Java
int a = 255;
byte b = (byte) a;
int c = b & 0xff; // Here be dragons
System.out.println(a);
System.out.println(b);
System.out.println(c);
Nous commençons par une valeur entière de 255, le convertir en un octet (devenant -1), puis reconvertir à un int en utilisant une formule magique. Le résultat attendu est:
255
-1
255
Je me demande si ce a & 0xff
est la façon la plus élégante de cette conversion. checkstyle par exemple se plaint de l'utilisation d'un nombre magique à cet endroit et ce n'est pas une bonne idée d'ignorer cette valeur pour cette vérification parce que dans d'autres endroits 255 peut vraiment être un nombre magique qui devrait être évité. Et c'est assez ennuyeux de définir une constante pour ce genre de choses par moi-même. Donc, je me demande s'il existe une méthode standard dans JRE qui fait cette conversion à la place? Ou peut-être une constante déjà définie avec la plus haute valeur d'octet non signé (similaire à Byte.MAX_VALUE qui est la plus haute valeur signée)
Donc pour garder la question courte: Comment puis-je convertir un octet en un int sans utiliser un nombre magique ?
Ok, jusqu'à présent, les possibilités suivantes ont été mentionnées:
- et continuer à utiliser
& 0xff
ignorer le nombre magique 255 checkstyle. Inconvénient: Les autres endroits qui peuvent utiliser ce numéro dans un autre domaine (pas les opérations sur les bits) ne sont pas vérifiés dans ce cas également. Avantage: Court et facile à lire. - Définissez ma propre constante et utilisez le code
& SomeConsts.MAX_UNSIGNED_BYTE_VALUE
. Inconvénient: Si j'en ai besoin dans différentes classes, je dois définir ma propre classe constante juste pour cette constante constante. Avantage: Pas de nombres magiques ici. Faites des calculs intelligents commeb & ((1 << Byte.SIZE) - 1)
. La sortie du compilateur est probablement la même car elle est optimisée à une valeur constante. Inconvénient: Assez de code, difficile à lire. Avantage: Tant que1
n'est pas défini comme nombre magique (checkstyle l'ignore par défaut), nous n'avons aucun nombre magique ici et nous n'avons pas besoin de définir des constantes personnalisées. Et quand les octets sont redéfinis pour être 16 bits un jour (juste plaisantant) alors cela fonctionne toujours parce que alors Byte.SIZE aura 16 et non 8.
Y a-t-il plus d'idées? Peut-être une autre opération astucieuse qui est plus courte que celle ci-dessus et n'utilise que des nombres comme 0 et 1?
Je ne suis pas tout à fait certain de ce que vous êtes vraiment essayer de faire ici, ou plutôt, pourquoi . ** ATTENTION: Ne mélangez pas les octets et les caractères! ** Un octet ne peut contenir que des caractères ASCII 7 bits * pas des caractères Java! * Les caractères Unicode ont une largeur de 21 bits, pas seulement 7 bits ** ni même 15/16 bits, * * non plus. Java représente en interne les caractères en unités de code UTF-16 de largeur variable (c'est-à-dire 1 ou 2) dans la plupart des situations (* exception: * java.unit.regex utilise nécessairement UTF-32 pour ses motifs). Vous ne pouvez pas raisonnablement masquer/sauvegarder seulement les 7 bits de poids faible d'une quantité de 21 bits et être laissé avec quelque chose de sensé et significatif. – tchrist
@tchrist: Je n'ai jamais mentionné de personnages ici. C'est juste des octets. Octets de 8 bits. Ni plus ni moins. – kayahr
Yah, d'accord. Mais * signé * quantités de 8 bits. – tchrist