Como você especifica um literal de byte em Java?


238

Se eu tiver um método

void f(byte b);

como posso chamá-lo com um argumento numérico sem conversão?

f(0);

dá um erro.


1
@oliholz que está downcasting com sobrecarga de análise adicionais
Ben Barkay

Respostas:


284

Você não pode. Uma constante numérica básica é considerada um número inteiro (ou longo, se seguido por um "L"), portanto, você deve explicitamente fazer o downcast para um byte para passá-lo como parâmetro. Tanto quanto eu sei, não há atalho.


11
Se você está fazendo muito desse tipo de coisa, pode definir um método auxiliar simples em byte b(int i) { return (byte) i; }algum lugar e importá-lo estaticamente. Então você pode escrever f (b (10)).
usar o seguinte

125

Você tem que lançar, eu tenho medo:

f((byte)0);

Acredito que realizará a conversão apropriada no momento da compilação, em vez do tempo de execução , portanto não causará penalidades de desempenho. É apenas inconveniente :(


11
+1 para conversão em tempo de compilação. É senso comum se vocês entenderem compiladores e tiverem fé em designers de linguagem (o que deveríamos), mas, caso contrário, não serão tão óbvios.
Philip Guin

31

Você pode usar um literal de byte em Java ... mais ou menos.

    byte f = 0;
    f = 0xa;

0xa(int literal) é convertido automaticamente em byte. Não é um literal de byte real (consulte JLS e comentários abaixo), mas se ele parecer um pato, eu o chamo de pato.

O que você não pode fazer é o seguinte:

void foo(byte a) {
   ...
}

 foo( 0xa ); // will not compile

Você deve transmitir da seguinte maneira:

 foo( (byte) 0xa ); 

Mas lembre-se de que tudo isso será compilado e eles estão usando "literais de bytes":

void foo(byte a) {
   ...
}

    byte f = 0;

    foo( f = 0xa ); //compiles

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

    foo( f = 1 );  //compiles

Claro que isso compila também

    foo( (byte) 1 );  //compiles

17
Estes não são literais de bytes. Eles são literais de vários outros tipos (int, principalmente) que estão sendo implicitamente convertidos em um byte. por exemplo, 1é um literal int, mas double d = 1;compila perfeitamente.
smehmood

Se você já está usando truques. Tenha uma importação estática de byte b(int i){}, então b(1), pelo menos e mais complicado que f=1.
Elazar Leibovich

1
@smehmood, mas desde que a conversão é feita pelo pré-compilador / compilador (antes mesmo de o programa começar a ser executado) e não pelo tempo de execução, é literal, não é?
Pacerier 8/09/14

2
@ Pacerier É um literal. Não é um "byte literal". É um int. O compilador o trata como um literal int (como deveria) e faz um downcast implícito na atribuição (como também deveria). Em nenhum momento ele é analisado como um "byte literal" (que não existe). Veja a Seção 5.2 do JLS, em particular a segunda metade, referente à restrição de conversões. As únicas coisas envolvidas são uma constante inteira e a aplicação de uma regra de conversão de atribuição apropriada a uma variável de bytes.
Jason C

Eu dei essa resposta +1 porque a técnica é nova, mas, de fato, não há "literais de bytes" em Java.

12

Se você está passando literais no código, o que impede você de simplesmente declará-lo com antecedência?

byte b = 0; //Set to desired value.
f(b);

1
Isso também permite atribuir ao valor um nome mais semântico. en.wikipedia.org/wiki/…
Aaron J Lang

Isso é útil. Se você está tentando preencher uma matriz de bytes usando o método 'fill' do java, isso é mais sensato.

O compilador apenas reclamou do seguinte, no entanto, e eu precisei adicionar o elenco: public static final byte BYTE_MASK = ( byte )0xff;
Marvo 27/07/12

E percebi que realmente queria, byte BYTE_MASK = 0x000000ff;para que eu não tivesse alguns erros de extensão de sinal desagradáveis.
Marvo

5

Que tal substituir o método por

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

isso permitirá f(0)


26
-1 Isso é muito ruim para a legibilidade do código. E pode causar problemas quando as pessoas realmente tentam transmitir um valor maior do que o byte pode conter. Eu desencorajo as pessoas a usar esse método!
Rolfツ

3
Além disso, esse elenco acontecerá em tempo de execução. Muito mal.
precisa saber é o seguinte

Concordando completamente com Rolf (Tsu), talvez valha a pena acrescentar que, tecnicamente, está sobrecarregando, não substituindo.
Cromax

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.