Як вказати байт-буквал на Java?


238

Якщо у мене є метод

void f(byte b);

як я можу викликати це числовим аргументом без введення?

f(0);

дає помилку.


1
@oliholz, що опустився, з додатковим синтаксичним розбором
Бен Баркай

Відповіді:


284

Ви не можете. Основна числова константа вважається цілим числом (або довгим, якщо за ним слідує "L"), тому потрібно явно скинути його на байт, щоб передати його як параметр. Наскільки я знаю, немає ярлика.


11
Якщо ви багато чого робите, ви можете byte b(int i) { return (byte) i; }десь визначити простий метод помічника та статично імпортувати його. Тоді ви можете написати f (b (10)).
Yona Appletree

125

Ви боюсь,

f((byte)0);

Я вважаю, що буде виконано відповідну конверсію під час компіляції -time замість часу виконання , тому насправді це не призведе до покарання за продуктивність. Це просто незручно :(


11
+1 для конверсії за час компіляції. Це здоровий глузд, якщо ви обидва розумієте компілятори і вірите в мовні дизайнери (що ми повинні), але в іншому випадку це не так очевидно.
Філіп Гін

31

Ви можете використовувати байт-буквал на Java ...

    byte f = 0;
    f = 0xa;

0xa(int literal) автоматично передається в байт. Це не справжній байт-буквал (див. JLS & коментарі нижче), але якщо він трясеться як качка, я називаю це качкою.

Що ви не можете зробити, це:

void foo(byte a) {
   ...
}

 foo( 0xa ); // will not compile

Ви повинні зробити так:

 foo( (byte) 0xa ); 

Але майте на увазі, що вони все зберуться, і вони використовують "байтові літерали":

void foo(byte a) {
   ...
}

    byte f = 0;

    foo( f = 0xa ); //compiles

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

    foo( f = 1 );  //compiles

Звичайно, це і компіляція

    foo( (byte) 1 );  //compiles

17
Це не байтові літерали. Вони є літералами різних інших типів (int, здебільшого), які неявно перетворюються на байт. наприклад, 1є int літералом, але double d = 1;компілюється просто чудово.
smehmood

Якщо ви вже використовуєте хитрощі. Мати статичний імпорт byte b(int i){}, то b(1)настільки ж тривалий і менш складний, ніж f=1.
Елазар Лейбович

1
@smehmood, Але оскільки перетворення здійснюється попереднім компілятором / компілятором (до того, як програма навіть почне працювати), а не час виконання, то це буквально чи не так?
Pacerier

2
@Pacerier Це буквально. Це не "байт-буквал". Це int. Компілятор розглядає це як int-літерал (як слід) і робить неявний низхід у призначенні (як і слід). Ні в якому разі не розбирається як "байт-буквал" (якого не існує). Див. Розділ 5.2 JLS, зокрема, останню половину щодо звуження конверсій. Єдині речі - це ціла константа і застосування відповідного правила перетворення призначення до змінної байтів.
Джейсон C

Я відповів на цю відповідь +1, оскільки методика є новою, але насправді у Java немає жодних "байт-літералів".

12

Якщо ви передаєте літерали в коді, що заважає вам просто оголосити це достроково?

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

1
Це також дозволяє дати значенню більш семантичне ім'я. en.wikipedia.org/wiki/…
Аарон Дж Ланг

Це корисно. Якщо ви намагаєтеся заповнити масив байтів за допомогою методу 'fill' Java, це найбільш розумно.

Однак компілятор просто поскаржився на наступне, і мені потрібно було додати акторський склад: public static final byte BYTE_MASK = ( byte )0xff;
Marvo

І я зрозумів, що насправді хотів, byte BYTE_MASK = 0x000000ff;щоб не отримати якихось помилкових помилок розширення знаків.
Марво

5

Як щодо перекриття методу

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

це дозволить f(0)


26
-1 Це дуже погано для читабельності коду. І це може спричинити проблеми, коли люди насправді намагаються передати значення, яке перевищує байт. Я заважаю людям використовувати цей метод!
Рольф ツ

3
Також цей склад буде відбуватися під час виконання. Дуже погано.
BrainSlugs83

Повністю погоджуючись з Рольфом (Цу), можливо, варто додати, що технічно це перевантаження, а не переважання.
Cromax

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.