Какие операнды можно использовать с оператором приращения в Java?

Я не знаю, что произойдет, если я применю оператор приращения к выражению в Java.

int ai[] = new ai[10];
ai[0]++;

// ***

class Car {
  public int yearMade = 0;
}

class Person {
  public Car myCar = new Car();
}

Person p = new Person();
p.myCar.yearMade++;

Можете ли вы увеличить элемент массива, как показано в первом примере?

Можете ли вы увеличить поле в классе (я знаю об инкапсуляции и геттерах/сеттерах, мой вопрос ориентирован на синтаксис-семантику), как показано во втором примере?

Я помню эпоху C/C++. Например, раньше была проблема с p -> x++. Иногда вам нужно было заключать сложные выражения в круглые скобки при использовании увеличения или уменьшения.

Спасибо за любые подсказки.


person Pavel Foltyn    schedule 09.09.2019    source источник
comment
Около часа я искал ответы на свои вопросы. Но людей интересуют разные вопросы, касающиеся инкремента/декремента. Префикс-постфикс, например. Ничего о приоритете операторов, скобках и т.д.   -  person Pavel Foltyn    schedule 09.09.2019
comment
Ваш вопрос заключался в том, можно ли это сделать. У вас даже есть код. Просто запусти и посмотри :D   -  person f1sh    schedule 09.09.2019
comment
Неа. Мне нужен систематический ответ, а не результат одного или двух случайных экспериментов. На oracle.com тоже не нашел. Если вы дадите мне ссылку на документацию, я перестану беспокоить пользователей stackoverflow.   -  person Pavel Foltyn    schedule 09.09.2019
comment
В любом случае, спасибо, @f1sh, за комментарий к моему вопросу.   -  person Pavel Foltyn    schedule 09.09.2019
comment
Без проблем. Оба эти примера возможны. :)   -  person f1sh    schedule 09.09.2019
comment
docs.oracle.com/javase/ спецификации/jls/se12/html/   -  person Johannes Kuhn    schedule 09.09.2019


Ответы (1)


Ответ на оба ваших вопроса: «Да, вы можете». И p.myCar.yearMade, и ai[0] являются переменными (переменная экземпляра и локальная переменная соответственно) и, таким образом, могут использоваться в качестве операндов для любого из этих четырех операторов.

4.12. Переменные

Переменная является местом хранения и имеет связанный тип, иногда называемый ее типом времени компиляции, который является либо примитивным типом (§4.2), либо ссылочным типом (§4.3).

Значение переменной изменяется с помощью присваивания (§15.26) или с помощью префикса или постфикса ++ (приращение) или -- (уменьшение) оператора (§15.14.2, §15.14.3, §15.15.1, § 15.15.2).

...

15.14.2. Постфиксный оператор приращения ++

Во время выполнения, если вычисление выражения операнда завершается внезапно, то выражение приращения постфикса завершается внезапно по той же причине, и приращение не происходит. В противном случае значение 1 добавляется к значению переменной, а сумма сохраняется обратно в переменную. Перед добавлением выполняется двоичное числовое преобразование (§5.6.2) для значения 1 и значение переменной. При необходимости сумма сужается сужающим примитивным преобразованием (§5.1.3) и/или подвергается упаковыванию преобразования (§5.1.7) в тип переменной до ее сохранения. Значением постфиксного выражения приращения является значение переменной перед сохранением нового значения.

person Andrew Tobilko    schedule 09.09.2019
comment
Спасибо. Это то, что я был после. - person Pavel Foltyn; 09.09.2019
comment
Можно еще два премиальных вопроса? class A { public Integer num = 0; public Integer getNum() { return num; } } A a = new A(); a.num++; a.getNum()++; Второй, наверное, бред. С другой стороны, геттер возвращает объект (целое число), поэтому у вас есть ссылка на этот объект, так что теоретически вы могли бы увеличить поле экземпляра, используя его геттер, не так ли? - person Pavel Foltyn; 09.09.2019
comment
@PavelFoltyn, это ерунда, которую я спрашивал некоторое время назад :) Что, если a.getNum() возвращает константу int, например 42? Компилятор понятия не имеет, будет ли это сгенерированное значение или переменная. Он должен точно знать, что это переменная (место хранения), чтобы он мог поместить результат оператора обратно в это хранилище. Иначе куда девать результат? - person Andrew Tobilko; 09.09.2019
comment
@PavelFoltyn общий термин CS, вероятно, L-value - person Andrew Tobilko; 09.09.2019
comment
@PavelFoltyn объект, возвращаемый getNum(), имеет тип Integer, который неизменяем. Вы не можете увеличить объект Integer, и нет перегрузки оператора для перенаправления оператора увеличения на какое-либо свойство. Однако, если вы можете разыменовать возвращаемый объект в переменную, вы можете увеличить переменную, например. methodReturningYourA().num++ работает, и точно так же будет работать выражение numericArrayReturningMethod()[index]++. - person Holger; 17.09.2019