Jak określić literał bajtowy w Javie?

238

Jeśli mam metodę

void f(byte b);

jak mogę to nazwać argumentem numerycznym bez rzutowania?

f(0);

daje błąd.

Charbel
źródło
1
@oliholz ​​to downcasting z dodatkowym parsowaniem
Ben Barkay

Odpowiedzi:

284

Nie możesz. Podstawowa stała numeryczna jest uważana za liczbę całkowitą (lub długą, jeśli następuje po niej „L”), więc musisz jawnie sprowadzić ją do bajtu, aby przekazać ją jako parametr. O ile mi wiadomo, nie ma skrótu.

Rudzik
źródło
11
Jeśli robisz dużo tego rodzaju rzeczy, możesz byte b(int i) { return (byte) i; }gdzieś zdefiniować prostą metodę pomocniczą i zaimportować ją statycznie. Następnie możesz napisać f (b (10)).
Yona Appletree
125

Obawiam się, że musisz rzucić:

f((byte)0);

Wierzę, że wykona odpowiednią konwersję w czasie kompilacji zamiast w czasie wykonywania , więc tak naprawdę nie spowoduje to obniżenia wydajności. To po prostu niewygodne :(

Jon Skeet
źródło
11
+1 za konwersję w czasie kompilacji. Rozumie się, że oboje rozumiesz kompilatory i wierzysz w projektantów języków (co powinniśmy), ale poza tym nie jest to takie oczywiste.
Philip Guin
31

Możesz użyć literału bajtu w Javie ... w pewnym sensie.

    byte f = 0;
    f = 0xa;

0xa(int dosłowne) jest automatycznie przesyłane do bajtów. To nie jest prawdziwy bajt dosłowny (patrz JLS i komentarze poniżej), ale jeśli kwacze jak kaczka, nazywam to kaczką.

Nie możesz tego zrobić:

void foo(byte a) {
   ...
}

 foo( 0xa ); // will not compile

Musisz rzucić w następujący sposób:

 foo( (byte) 0xa ); 

Pamiętaj jednak, że wszystkie się skompilują i używają „literałów bajtowych”:

void foo(byte a) {
   ...
}

    byte f = 0;

    foo( f = 0xa ); //compiles

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

    foo( f = 1 );  //compiles

Oczywiście to też się kompiluje

    foo( (byte) 1 );  //compiles
RickHigh
źródło
17
To nie są literały bajtowe. Są to literały różnego rodzaju (głównie int), które są domyślnie konwertowane na bajt. np. 1jest int dosłowne, ale double d = 1;dobrze się kompiluje.
smehmood
Jeśli już używasz sztuczek. Miej statyczny import byte b(int i){}, a następnie b(1)tak długi i mniej trudny niż f=1.
Elazar Leibovich,
1
@smehmood, ale ponieważ konwersja jest wykonywana przez prekompilator / kompilator (zanim program zacznie się uruchamiać), a nie przez środowisko wykonawcze, to jest to dosłowne, prawda?
Pacerier
2
@Pacerier To dosłownie. To nie jest „bajt dosłowny”. To jest int. Kompilator traktuje to jako literał int (tak jak powinien) i wykonuje ukryte spowolnienie zadania (tak jak powinien). W żadnym momencie nie jest on analizowany jako „bajt dosłowny” (który nie istnieje). Patrz sekcja 5.2 JLS, w szczególności ta druga połowa dotycząca zwężania konwersji. Jedyne rzeczy, których to dotyczy, to stała całkowita i zastosowanie odpowiedniej reguły konwersji przypisania do zmiennej bajtowej.
Jason C
Dałem tę odpowiedź +1, ponieważ technika jest nowatorska, ale w rzeczywistości w Javie nie ma „literałów bajtowych”.
12

Jeśli przekazujesz literały w kodzie, co powstrzymuje cię od zwykłego zadeklarowania go przed czasem?

byte b = 0; //Set to desired value.
f(b);
Mike Yockey
źródło
1
Pozwala to również nadać wartości bardziej semantyczną nazwę. en.wikipedia.org/wiki/…
Aaron J Lang
To jest przydatne. Jeśli próbujesz wypełnić tablicę bajtów przy użyciu metody „fill” języka Java, jest to najbardziej sensowne.
Kompilator właśnie narzekał na następujące rzeczy i musiałem dodać obsadę: public static final byte BYTE_MASK = ( byte )0xff;
Marvo
I zdałem sobie sprawę, że tak naprawdę chciałem, byte BYTE_MASK = 0x000000ff;aby nie dostać paskudnych błędów związanych z przedłużaniem znaków.
Marvo
5

Co z zastąpieniem metody za pomocą

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

to pozwoli f(0)

Boris Pavlović
źródło
26
-1 To bardzo źle wpływa na czytelność kodu. I może powodować problemy, gdy ludzie faktycznie próbują przekazać wartość wyższą niż bajt może pomieścić. Odradzam ludziom korzystanie z tej metody!
Rolf ツ
3
Ponadto obsada ta nastąpi w czasie wykonywania. Bardzo źle.
BrainSlugs83
Całkowicie zgadzając się z Rolfem (Tsu), być może warto dodać, że technicznie jest to przeciążanie, a nie zastępowanie.
Cromax,