Разница между a + = 10 и a = a + 10 в java?

Являются ли a += 10 и a = a + 10 одинаковыми, или есть какая-то разница между ними? Я задал этот вопрос, изучая задания на Java.

Ответ 1

Как вы уже упоминали о литье... в этом случае есть разница:

byte a = 5;
a += 10; // Valid
a = a + 10; // Invalid, as the expression "a + 10" is of type int

Из спецификации языка Java раздел 15.26.2:

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

Интересно, пример, который они приводят в спецификации:

short x = 3;
x += 4.6;

действителен в Java, но не в С#... в основном на С# компилятор выполняет специальную оболочку + = и - =, чтобы гарантировать, что это выражение является либо типом цели, либо является литералом в пределах диапазона целевого типа.

Ответ 2

Нет никакой разницы, одна - сокращенная для другой. Даже компилятор будет генерировать те же инструкции для обоих.

Изменить: компилятор НЕ генерирует тот же код для обоих, как я только что узнал. Проверьте это:

dan$ cat Test.java
public class Test {
    public static void main(String[] args) {
        int a = 0;
        a = a + 10;
        a += 20;
    }
}

dan$ javap -c Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   bipush  10
   5:   iadd
   6:   istore_1
   7:   iinc    1, 20
   10:  return

}

Итак, короткий ответ, особенно для начинающего Java, или любого, кто не беспокоится об оптимизации на самом маленьком уровне, заключается в том, что они взаимозаменяемы. Длительный ответ будет зависеть от того, что я читаю о iadd vs iinc.

Изменить 2: Хорошо, я вернулся. Спецификации команд (примерно) следующие:

iadd - добавляет две верхние строки в стек

iinc - увеличивает локальную переменную константой

И как мы видели выше, мы можем сохранить пару инструкций с помощью iinc, если в правой части есть константа.

Но что произойдет, если мы имеем

a += a?

Затем код выглядит следующим образом:

   7:   iload_1
   8:   iload_1
   9:   iadd
   10:  istore_1

что мы получаем, если мы имеем a = a + a.

Ответ 3

Это определено в Спецификация языка Java, раздел 15.25.2. Основная часть:

Выражение составного присваивания форма E1 op = E2 эквивалентна E1 = (T) ((E1) op (E2)), где T - тип E1, за исключением того, что E1 является оценивается только один раз.

То есть, в вашем случае разница заключается в неявном типе:

byte a = 100;
a += 1000;    // compiles
a = a + 1000; // doesn't compile, because an int cannot be assigned to a byte.

Ответ 4

В выражениях, которые вы показываете, они эквивалентны в выражении типа:

array[getIndex(context)][some / complex + expression] += offset;

вы получаете представление о том, в каких ситуациях полезен оператор + = (и другие операторы присваивания). Если выражение нетривиально, оператор + = предотвращает ошибки и улучшает читаемость и, следовательно, ремонтопригодность.

Ответ 5

В поле S/W есть несколько терминов, я могу объяснить это вам,

в a=a+1 назначение a измеряется после двух шагов

  • Система вычисляет значение a (здесь создается новая изолированная копия)
  • Система добавляет 10 к изолированной переменной a, тогда значение выделенной a назначается левой стороне a

Но во втором случае

  • Система знает значение a и напрямую добавляет 10 к (здесь не было выделенной изолированной копии).

Надеемся, что это будет полезно для вас, и, кроме того, мы обычно используем метод a += 10;, поскольку он снижает стоимость операции, как и другие,