Сложение 2 чисел типа short в Java

512
29 декабря 2016, 06:49

Итак, тип short - от -32768 до 32767.

Простой код:

short x1 = 5, x2 = 38;
x1 = x1 + x2;
System.out.println(x1);

Ругается на ошибку, просит привести к типу int:

Uncompilable source code - incompatible types: possible lossy conversion from int to short

Хотя казалось бы, почему - сложение двух чисел одного типа.

Но такой код, как ни странно, работает без ошибок:

short x1 = 5, x2 = 38;
x1 += x2;
System.out.println(x1);

Вывод: 43

Почему?

Answer 1

Любые арифметические операции над типом short на выходе дают int (результат автоматически кастуется в int). В случае же с x1 += x2 по факту происходит x1 = (short) (x1 + x2)

При вычислении выражения (a @ b) аргументы a и b преобразуются в числа, имеющие одинаковый тип:

  • если одно из чисел double, то в double
  • иначе, если одно из чисел float, то в float
  • иначе, если одно из чисел long, то в long
  • иначе, оба числа преобразуются в int

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

Answer 2

Это особенности преобразования типов в Java.

5.6.2. Binary Numeric Promotion

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:

...

Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

...

Otherwise, both operands are converted to type int.

Полное описание правил преобразования типов Java Language Specification

Answer 3

Согласно спецификации Java SE 8 Edition (15.26.2 Compound Assignment Operators)

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

то есть имеет место явное приведение типа правого выражения к типу левого выражения

E1 = (T) ((E1) op (E2))
    ^^^^

Для вашего примера данное предложение

x1 += x2;

эквивалентно согласно приведенной цитате следующему предложению

x1 = ( short )( x1 + x2 );

Для не составного оператора присваивания такого явного приведения типов нет, а потому вы сами должны применять явное приведение типов, если таковое требуется, и в данном примере

short x1 = 5, x2 = 38;
x1 = x1 + x2;

так как тип выражения x1 + x2 является int а левый операнд имеет тип short, то есть имеет место "сужение" значения то следует написать

short x1 = 5, x2 = 38;
x1 = ( short )( x1 + x2 );

Думаю, что будет важно отметить для расширения кругозора, что тоже самое правило имеет место и в C#. То есть в отношении этой операции Java и C# ведут себя одинаково. Данный код

short x1 = 5, x2 = 38;
x1 = x1 + x2;

также не будет компилироваться в C#, тогда как данный код

short x1 = 5, x2 = 38;
x1 += x2;

успешно скомпилируется, так как возможно явное преобразование из типа int в тип short.

READ ALSO
Как применить псевдокласс :hover

Как применить псевдокласс :hover

Как применить псевдокласс :hover к такому классу: headermain-header

532
Не работают медиа запросы без !important

Не работают медиа запросы без !important

Использую отдельный файл mediasass для написания медиа-запросов

779
Нюанс с column-count

Нюанс с column-count

Здравствуйте! Имеется контейнерblock, в котором размещены три блока

540
Как открыть две формы одновременно?

Как открыть две формы одновременно?

Как одним методом открыть две формы одновременно?

556