Как вы указываете байтовый литерал в Java?


238

Если у меня есть метод

void f(byte b);

как я могу назвать это с числовым аргументом без приведения?

f(0);

выдает ошибку.


1
@oliholz, который уныл с дополнительными
разборками

Ответы:


284

Ты не можешь. Базовая числовая константа считается целым числом (или длинной, если за ней следует буква «L»), поэтому вы должны явно уменьшить ее до байта, чтобы передать его в качестве параметра. Насколько я знаю, ярлыка нет.


11
Если вы делаете много такого рода вещей, вы можете определить byte b(int i) { return (byte) i; }где-нибудь простой вспомогательный метод и статически импортировать его. Тогда вы можете написать f (b (10)).
Йона Апплетри

125

Вы должны бросить, я боюсь

f((byte)0);

Я считаю, что это будет выполнять соответствующее преобразование во время компиляции, а не во время выполнения , так что на самом деле это не приведет к снижению производительности. Это просто неудобно :(


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

18
Это не байтовые литералы. Это литералы множества других типов (в основном int), которые неявно преобразуются в байт. например, 1является литералом типа int, но double d = 1;компилируется просто отлично.
smehmood

Если вы уже используете трюки. Имейте статический импорт byte b(int i){}, тогда b(1)как длинный и менее сложный, чем f=1.
Элазар Лейбович

1
@smehmood, но поскольку преобразование выполняется прекомпилятором / компилятором (до того, как программа даже запустится), а не во время выполнения, то это литерал, не так ли?
Pacerier

2
@Pacerier Это буквально. Это не «байтовый литерал». Это инт. Компилятор обрабатывает его как литерал int (как и должно быть) и выполняет неявное уменьшение в присваивании (как и должно быть). Ни при каких условиях он не анализируется как «байтовый литерал» (которого не существует). См. JLS Раздел 5.2, в частности, вторую половину, касающуюся сужающих преобразований. При этом используются только целочисленная константа и применение соответствующего правила преобразования присваивания к байтовой переменной.
Джейсон С

Я дал этот ответ +1, потому что техника нова, но на самом деле в Java нет никаких «байтовых литералов».

12

Если вы передаете литералы в коде, что мешает вам просто объявить это заранее?

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

1
Это также позволяет вам присвоить значению более семантическое имя. en.wikipedia.org/wiki/…
Аарон Дж. Ланг

Это полезно Если вы пытаетесь заполнить массив байтов, используя Java-метод 'fill', это наиболее разумно.

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

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

5

Как насчет переопределения метода с

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

это позволит f(0)


27
-1 Это очень плохо для читабельности кода. И может вызвать проблемы, когда люди на самом деле пытаются передать значение выше, чем может содержать байт. Я отговариваю людей от использования этого метода!
Рольф ツ

4
Кроме того, это приведение произойдет во время выполнения. Очень плохо.
BrainSlugs83

Полностью согласившись с Рольфом (Tsu), возможно, стоит добавить, что технически это перегрузка, а не переопределение.
Cromax

-2

В Java 7 и более поздних версиях вы можете указать байтовый литерал следующим образом: byte aByte = (byte)0b00100001;

Ссылка: http://docs.oracle.com/javase/8/docs/technotes/guides/language/binary-literals.html


20
двоичный литерал! = байтовый литерал.
Марчелло Нуччо

Вы все еще преобразуете в байты.
М.Казем Ахгари
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.