Почему Java + +, - =, * =, / = составные операторы присваивания не требуют приведения? - PullRequest
3492 голосов
/ 03 января 2012

До сегодняшнего дня я думал, что например:

i += j;

Был просто ярлык для:

i = i + j;

Но если мы попробуем это:

int i = 5;
long j = 8;

Тогда i = i + j; не скомпилируется, но i += j; скомпилируется нормально.

Означает ли это, что на самом деле i += j; является ярлыком для чего-то вроде этого i = (type of i) (i + j)

Ответы [ 11 ]

1 голос
/ 08 марта 2019

Спецификация языка Java определяет E1 op= E2 как эквивалент E1 = (T) ((E1) op (E2)), где T является типом E1, а E1 оценивается один раз .

Этотехнический ответ, но вам может быть интересно, почему это так.Что ж, давайте рассмотрим следующую программу.

public class PlusEquals {
    public static void main(String[] args) {
        byte a = 1;
        byte b = 2;
        a = a + b;
        System.out.println(a);
    }
}

Что печатает эта программа?

Вы догадались 3?Жаль, что эта программа не скомпилируется.Зачем?Ну, так получилось, что добавление байтов в Java определено так, чтобы возвращать int.Я полагаю, это произошло потому, что виртуальная машина Java не определяет байтовые операции для сохранения в байтовых кодах (в конце концов, их число ограничено), а использование целочисленных операций - это деталь реализации, представленная на языке.

Но если a = a + b не работает, это будет означать, что a += b никогда не будет работать для байтов, если было определено, что E1 += E2 равняется E1 = E1 + E2.Как показывает предыдущий пример, это действительно так.В качестве хака, заставляющего оператор += работать для байтов и шортов, подразумевается неявное приведение.Это не так здорово, но во время работы над Java 1.0 основное внимание уделялось выпуску языка с самого начала.Теперь из-за обратной совместимости этот хак, введенный в Java 1.0, не может быть удален.

...