Продвижение на Яве? - PullRequest
       19

Продвижение на Яве?

23 голосов
/ 02 ноября 2009

Правила для продвижения - «когда операнды бывают разных типов, автоматическое двоичное числовое продвижение происходит с преобразованием меньшего типа операнда в больший». Но операнды одного типа, например,

byte=byte+byte // Compile time error... found int..

Так почему же так?

Ответы [ 5 ]

43 голосов
/ 02 ноября 2009

Нет оператора + для byte. Вместо этого оба операнда переводятся в int, поэтому вы получаете

byte = byte + byte
... becomes (widening to find + operator) ...
byte = int + int
... becomes (result of + operator) ...
byte = int 

... который затем завершается ошибкой, потому что нет неявного преобразования из int в byte. Вам необходимо разыграть:

byte a = 1;
byte b = 2;

byte c = (byte) (a + b);

Вот фактические правила для числового продвижения из раздела 5.6.2 JLS :


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

  • Если какой-либо из операндов относится к ссылочному типу, выполняется преобразование без распаковки (§5.1.8). Тогда:
  • Если один из операндов имеет тип double, другой преобразуется в двойной.
  • В противном случае, если один из операндов имеет тип float, другой преобразуется в float.
  • В противном случае, если один из операндов имеет тип long, другой преобразуется в long.
  • В противном случае оба операнда преобразуются в тип int.
17 голосов
/ 02 ноября 2009

Вам был предоставлен правильный ответ об автоматическом продвижении на 'int'.

Есть еще одно замечание - составные операторы присваивания ведут себя так, как будто имеют неявный регистр типов. Пример:

byte b1 = 1;
byte b2 = 2;
b1 = b1 + b2; // compilation fails
b1 += b2; // compilation successful
2 голосов
/ 06 октября 2018

Чтобы понять это, вы должны обратиться к 2 вещам:

неявное приведение: байт (8 бит) -> короткий (16 бит) -> int (32 бит) -> float (32 бит) -> двойной (64 бит) char (16 бит) -> int (32 бит)

Правила арифметических операторов

  1. Правило приоритета оператора: это правило гласит, что сначала будет оцениваться группа (*, /,%). Тогда группа операторов (+, -) будет оценена. Из той же группы операторов рассчитайте слева.

  2. Правило продвижения операндов. Это правило гласит, что операнды с типом данных, меньшим, чем int, будут преобразованы в int. порядок продвижения (byte-> short-> int, char-> int)

  3. Правило операнда того же типа: это правило гласит, что если оба операнда int, long, float, double, тогда один и тот же тип переносится в тип результата. то есть long + long => long, float + float => float, int + int => int

  4. Правило операнда смешанного типа: следуйте порядку повышения (int-> long-> float-> double), если какой-либо из операндов относится к указанному выше порядку, то меньший будет повышен до большего и получится будет рассчитан на больший тип. то есть long + double => double, int + long => long

1 голос
/ 07 февраля 2017

Я хотел бы поговорить о продвижении в целом

Java может оценивать только арифметические выражения, в которых типы операндов идентичны

Например, в выражении, содержащем значения int и double, значения int переводятся в двойные значения для использования в выражении.

другими словами

double someVar = 1 / 2;// someVar = 0

но

double someVar = (double)1 / 2;// someVar = 0.5

почему?

  • мы используем (double) cast operator, чтобы создать temporary копия его операнда с плавающей точкой "1" (она называется explicit conversion)
  • Теперь вычисление состоит из значения с плавающей точкой (временная двойная копия 1), деленного на целое число 2
  • согласно приведенному выше утверждению, Java выполняет операцию, называемую promotion (или неявное преобразование), поэтому int values повышается до double values для использования in выражение => целое число 2 повышается до двойного
  • выражение стало double someVar = 1.0 / 2.0; // someVar= 0.5

надеюсь, что это полезно, даже если это выходит за рамки вопроса

0 голосов
/ 17 января 2014

С на этот вопрос SO , и выше ответы из-за + арифметического оператора, оба операнда преобразуются в тип int.

byte b1 = 1;
byte b2 = 2;
byte b3 = b1 + b2; // compile time error

В приведенном выше коде значения b1 и b2 будут разрешены во время выполнения, поэтому компилятор преобразует оба значения в int перед разрешением значения.

Но если мы рассмотрим следующий код,

final byte b1 = 1;
final byte b2 = 2;
int b3 = b1 + b2; // constant expression, value resolved at compile time

b1 и b2 являются окончательными переменными, и значения будут разрешены во время компиляции, поэтому компиляция не будет завершена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...