2016-04-11 12 views
5

Я встретил недоразумение примитивного продвижения в следующем фрагменте кода.примитивное продвижение для >> [Java]

byte a = 2; 
int b = a >> 4L; 

Что я ожидал бы?

long b = (int)a >> 4L;
long b = a >> 4L;
int b = a >> 4L;

int >> long будет способствовать большему типу данных (long), и он не будет компилировать с результатом int типа.

Что я получил?

Он компилируется в порядке. Почему?

+1

Правила расширения не замечают двоичную операцию, только самый широкий операнд, например. 'x% (byte) b' не может быть шире, чем' byte', и все же он никогда не является 'byte' –

ответ

3

JLS не будет «продвигать к более крупному типу данных» здесь, потому что он не выполняет двоичное числовое продвижение для операторов переноса. Это покрывает JLS, Section 15.19.

Унарное цифровое продвижение (§5.6.1) выполняется для каждого операнда отдельно. (Binary числовое расширение (§5.6.2) является не выполняются над операндами.)

Унарное числовое расширение способствует байт a к int. Литерал 4L не изменяется, но в любом случае он должен быть целостным.

Это ошибка времени компиляции, если тип каждого из операндов оператора сдвига после унарной цифровой рекламы не является примитивным интегральным типом.

Для смещения для сдвига int используются только наименее 5 значащих бит.

Если продвинутый тип левого операнда является int, тогда только пять младших бит правого операнда используются в качестве расстояния сдвига. Это как если бы правый операнд подвергался побитовому логическому оператору И & (§15.22.1) с значением маски 0x1f (0b11111). Поэтому фактически используемое расстояние сдвига всегда находится в диапазоне от 0 до 31 включительно.

Результат оператора является int, не long, поэтому он может быть назначен на int без ошибок компилятора.

Тип выражения сдвига - это продвинутый тип левого операнда.

1

К JLS:

Тип выражения сдвига является расширенный тип левого операнда.

Правый операнд оператора сдвига не влияет на тип выражения. В отличие от оператора, такого как +, больший тип справа не означает, что результат может быть больше или меньше.