Почему операторы присваивания сCompound типа в Java (+=, -=, *=, /=) не требуют приведения типов?
Описание проблемы:
Я всегда считал, что следующий код:
i += j;
является просто короткой записью для:
i = i + j;
Однако, если мы попробуем следующий код:
int i = 5;
long j = 8;
то выражение i = i + j;
не компилируется, в то время как i += j;
компилируется без ошибок.
Вопрос: означает ли это, что i += j;
на самом деле является сокращением для чего-то вроде:
i = (тип i) (i + j);
Таким образом, происходит неявное преобразование типов?
4 ответ(ов)
Да,
по сути, когда мы пишем
i += l;
компилятор преобразует это в
i = (int) (i + l);
Я только что проверил код в .class
файле.
Действительно полезно знать!
В случае, если вам нужно выполнить операцию i = i + l
, вы должны явно привести long
к int
, чтобы компиляция завершилась успешно и результат был корректным. Например:
i = i + (int)l;
Или
i = (int)((long)i + l); // это то, что происходит в случае использования оператора +=, здесь не требуется явное приведение (long), так как верхнее приведение выполняется неявно.
Однако при использовании оператора +=
тип приведения выполняется неявно. Оператор автоматически приводит тип правого операнда к типу левого операнда, поэтому явное приведение не требуется.
Проблема здесь связана с приведением типов.
Когда вы складываете значение типа int
и значение типа long
:
- объект типа
int
приводится к типуlong
, после чего оба значения складываются, и результатом будет объект типаlong
. - Однако объект типа
long
не может быть неявно приведён к типуint
, поэтому вам нужно сделать это явно.
Тем не менее, операция +=
реализована таким образом, что она выполняет приведение типов автоматически. То есть, это эквивалентно записи i = (int) (i + m)
.
Вопрос о преобразовании типов в процессе выполнения может действительно возникнуть на собеседовании.
Рассмотрим следующий код:
int a = 2;
long b = 3;
a = a + b;
Здесь не происходит автоматического приведения типов. В C++ компиляция пройдет успешно, однако в Java вы получите ошибку Incompatible type exception
, так как попытка присвоить результат вычисления переменной типа long
переменной типа int
приводит к несоответствию типов.
Чтобы избежать этой ошибки, вы можете записать код следующим образом:
int a = 2;
long b = 3;
a += b; // Нет ошибки компиляции или исключения благодаря автоматическому приведению типов
В этом случае оператор +=
позволяет избежать явного приведения типов и корректно обработает сложение, используя тип int
для переменной a
.
Инициализация ArrayList в одну строчку
Что значит "Не удалось найти или загрузить основной класс"?
Как установить Java 8 на Mac
Почему в RecyclerView отсутствует onItemClickListener()?
Что значит 'synchronized'?