Comment spécifiez-vous un littéral d'octet en Java?

238

Si j'ai une méthode

void f(byte b);

comment puis-je l'appeler avec un argument numérique sans transtyper?

f(0);

donne une erreur.

Charbel
la source
1
@oliholz ​​qui est abattu avec des frais supplémentaires d'analyse syntaxique
Ben Barkay

Réponses:

284

Vous ne pouvez pas. Une constante numérique de base est considérée comme un entier (ou longue si elle est suivie d'un "L"), vous devez donc explicitement la convertir en octet pour la passer en paramètre. Pour autant que je sache, il n'y a pas de raccourci.

Robin
la source
11
Si vous faites beaucoup de choses de ce genre, vous pouvez définir une méthode d'assistance simple byte b(int i) { return (byte) i; }quelque part et l'importer statiquement. Ensuite, vous pouvez écrire f (b (10)).
Yona Appletree
125

Vous devez lancer, j'ai peur:

f((byte)0);

Je crois que cela effectuera la conversion appropriée au moment de la compilation au lieu du temps d' exécution , donc cela ne causera pas réellement de pénalités de performances. C'est juste gênant :(

Jon Skeet
la source
11
+1 pour la conversion au moment de la compilation. C'est du bon sens si vous comprenez tous les deux les compilateurs et que vous avez confiance dans les concepteurs de langage (ce que nous devrions), mais sinon ce n'est pas si évident.
Philip Guin
31

Vous pouvez utiliser un littéral d'octet en Java ... en quelque sorte.

    byte f = 0;
    f = 0xa;

0xa(int littéral) est automatiquement converti en octets. Ce n'est pas un vrai littéral d'octets (voir JLS et commentaires ci-dessous), mais si ça craque comme un canard, je l'appelle un canard.

Ce que vous ne pouvez pas faire, c'est ceci:

void foo(byte a) {
   ...
}

 foo( 0xa ); // will not compile

Vous devez lancer comme suit:

 foo( (byte) 0xa ); 

Mais gardez à l'esprit que ceux-ci seront tous compilés, et ils utilisent des "littéraux d'octet":

void foo(byte a) {
   ...
}

    byte f = 0;

    foo( f = 0xa ); //compiles

    foo( f = 'a' ); //compiles

    foo( f = 1 );  //compiles

Bien sûr, cela compile aussi

    foo( (byte) 1 );  //compiles
RickHigh
la source
18
Ce ne sont pas des littéraux d'octets. Ce sont des littéraux d'une variété d'autres types (int, principalement) qui sont implicitement convertis en octets. par exemple, 1est un littéral int, mais se double d = 1;compile très bien.
smehmood
Si vous utilisez déjà des astuces. Avoir une importation statique de byte b(int i){}, puis b(1)aussi longue et moins compliquée que f=1.
Elazar Leibovich
1
@smehmood, Mais puisque la conversion est effectuée par le pré-compilateur / compilateur (avant même que le programme ne démarre) et non par le runtime, alors c'est un littéral non?
Pacerier
2
@Pacerier C'est un littéral. Ce n'est pas un "littéral d'octet". C'est un int. Le compilateur le traite comme un littéral int (comme il se doit) et effectue un abaissement implicite dans l'affectation (comme il le devrait également). À aucun moment il n'est analysé comme un "littéral d'octet" (qui n'existe pas). Voir JLS Section 5.2 en particulier la seconde moitié concernant le rétrécissement des conversions. Les seules choses impliquées sont une constante entière et l'application d'une règle de conversion d'affectation appropriée à une variable d'octet.
Jason C
J'ai donné cette réponse +1 parce que la technique est nouvelle, mais en effet, il n'y a pas de "littéraux d'octets" en Java.
12

Si vous passez des littéraux dans le code, qu'est-ce qui vous empêche de simplement le déclarer à l'avance?

byte b = 0; //Set to desired value.
f(b);
Mike Yockey
la source
1
Cela vous permet également de donner à la valeur un nom plus sémantique. en.wikipedia.org/wiki/…
Aaron J Lang
C'est utile. Si vous essayez de remplir un tableau d'octets en utilisant la méthode 'fill' de java, c'est très judicieux.
Cependant, le compilateur vient de se plaindre des éléments suivants et j'ai dû ajouter le casting: public static final byte BYTE_MASK = ( byte )0xff;
Marvo
Et je me suis rendu compte que je voulais vraiment byte BYTE_MASK = 0x000000ff;éviter d'avoir des bugs d'extension de signe méchant.
mars 2012
5

Qu'en est-il de la substitution de la méthode avec

void f(int value)
{
  f((byte)value);
}

cela permettra f(0)

Boris Pavlović
la source
27
-1 C'est très mauvais pour la lisibilité du code. Et cela pourrait causer des problèmes lorsque les gens essaient réellement de transmettre une valeur supérieure à ce que l'octet peut contenir. Je décourage les gens d'utiliser cette méthode!
Rolf
4
En outre, cette distribution se produira au moment de l'exécution. Très mauvais.
BrainSlugs83
Entièrement d'accord avec Rolf (Tsu), il vaut peut-être la peine d'ajouter, que techniquement c'est une surcharge, pas une priorité.
Cromax