Основные арифметические операции над int - Java

Недавно я заметил идиосинкразию Java относительно основных арифметических операций в Java. Со следующим кодом

byte a = 3;
byte b = 4;
byte c = a * b;

Я получаю ошибку компиляции типа "несоответствие"...

Являются ли основные арифметические операции в Java (+, -, *, /) выполняются только для примитивных типов данных int и более высокого порядка (long, double и т.д.), тогда как арифметические операции на byte и short сначала переносятся на int, а затем вычисляются?

Ответ 1

Операции с byte, char и short расширяются до int, если компилятор не может определить значение в диапазоне.

final byte a = 3, b = 4;
byte c = a * b; // compiles

final byte a = 3, b = 40;
byte c = a * b; // compiles

final int a = 3, b = 4;
byte c = a * b; // compiles !!

но

byte a = 3, b = 4;
byte c = a * b; // doesn't compile as the result of this will be `int` at runtime.

final byte a = 30, b = 40;
byte c = a * b; // doesn't compile as the value is too large, will be an `int`

BTW Это компилируется, хотя это приводит к переполнению.:]

final int a = 300000, b = 400000;
int c = a * b; // compiles but overflows, is not made a `long`

Ответ 2

Результатом целых операций является либо int, либо long. Это указано в JLS:

4.2.2. Целые операции

Численные операторы , которые приводят к значению типа int или long:

  • Унарные операторы плюс и минус + и - (§15.15.3, §15.15.4)

  • Мультипликативные операторы *,/и% (§15.17)

  • Аддитивные операторы + и - (§15.18)

  • ...

Также:

5.6.2. Двоичное числовое продвижение

Когда оператор применяет двоичное числовое продвижение к паре операндов, каждый из которых должен обозначать значение, которое можно конвертировать в числовой тип, применяются следующие правила, чтобы:

Расширение примитивного преобразования (§5.1.2) применяется для преобразования одного или обоих операндов, как указано в следующих правилах:

  • Если один из операндов имеет тип double, другой преобразуется в double.

  • В противном случае, если любой операнд имеет тип float, другой преобразуется в float.

  • В противном случае, если любой из операндов имеет тип long, другой преобразуется в long.

  • В противном случае оба операнда преобразуются в тип int.

...

Для операндов определенных операторов выполняется двоичное числовое продвижение:

  • Мультипликативные операторы *,/и% (§15.17)

  • Операторы сложения и вычитания для числовых типов + и - (§15.18.2)

  • Операторы численного сравнения <, < =, > , & >= (§15.20.1)

  • Операторы численного равенства == и!= (§15.21.1)

  • Целочисленные побитовые операторы &, ^ и | (§15.22.1)

  • В некоторых случаях условный оператор?: (§15.25)