В Java 8 JLS также говорится в §5.6.1:
5.6.1. Унарное числовое продвижение
Некоторые операторы применяют унарное числовое продвижение к одному операнду, который должен давать значение числового типа:
...
- В противном случае, если операнд имеет тип времени компиляции
byte
, short
или char
, он повышается до значения типа int
расширяющимся примитивным преобразованием (§5.1.2).
...
Таким образом, если взять следующее выражение:
int i = ...
short s = (short) i << 2;
Приведет к ошибке компилятора:
Main.java:4: error: incompatible types: possible lossy conversion from int to short
short s = (short) i << 2;
Демонстрация Ideone
Это связано с тем, что приведение типов привязывается к первому аргументу сдвига, а не ко всему выражению. Вот полное выражение с явными скобками:
short s = ((byte) i) << 2;
В то время как
int i = ...;
int j = (short) i << 2;
Будет успешно компилироваться.
Демонстрация Ideone
Таким образом, эффективные биты, которые нужно использовать для чего-либо < int
, такие же, как и для int
(5
битов), поскольку они автоматически повышаются до int
.
Если вы приведете результат всего выражения к, например, short
(short s = (short) (i << 2)
, тогда в компиляторе нет автоматизма. Но Богемский ответ дает логическую оценку того, что биты правого оператора будут эффективно влиять на значение после приведения.
В более новых версиях JLS раздел был изменен. Например, в Java 14 JLS, §5.6 мы находим (раздел сокращен для краткости, я рекомендую прочитать весь абзац, чтобы получить полный контекст):
5.6. Числовые контексты
Числовые контексты применяются к операндам арифметических операторов, выражениям создания массивов и доступа к ним, условным выражениям и выражениям результатов выражений переключения.
Выражение появляется в числовом арифметическом контексте, если выражение является одним из следующих:
...
- Операнд оператора сдвига
<<
, >>
или >>>
(§15.19). Операнды этих операторов сдвига рассматриваются отдельно, а не как группа. Расстояние сдвига long
(правый операнд) не способствует сдвигу значения (левый операнд) на long
.
...
Числовое продвижение определяет продвигаемый тип всех выражений в числовом контексте. Повышенный тип выбирается таким образом, чтобы каждое выражение можно было преобразовать в повышенный тип, и в случае арифметической операции операция определяется для значений повышенного типа. Порядок выражений в числовом контексте не имеет значения для числового продвижения. Правила следующие:
...
Затем расширяющееся примитивное преобразование (§5.1.2) и сужающее примитивное преобразование (§5.1.3) применяются к некоторым выражениям в соответствии со следующими правилами:
...
В противном случае ни одно из выражений не относится к типу double
, float
или long
. В этом случае вид контекста определяет, как будет выбран продвигаемый тип.
В числовом арифметическом контексте или контексте числового массива повышенным типом является int
, а любые выражения, не принадлежащие к типу int, подвергаются расширяющему примитивному преобразованию в int
.
В контексте числового выбора применяются следующие правила:
...
- Otherwise, the promoted type is
int
, and all the expressions that are not of type int
undergo widening primitive conversion to int
.
...
person
Turing85
schedule
18.08.2020