Постинкремент Java (++) не работает должным образом при передаче в качестве параметра

Я столкнулся со следующей проблемой:

private void doStuff(int i) {
   if(i>10) {
      return;
   }
   doStuff(i++); 
}

public void publicMethod() {
   doStuff(i);
}

Я ожидаю, что это будет работать doStuff 10 раз, а затем вернуться.

тем не мение i++ не исполняется до doStuff снова вызывается с 0,

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

4 ответа

Решение

Теперь я ожидал бы, что это запустит doStuff 10 раз, а затем вернется, однако i++ не выполнится, пока doStuff снова не будет вызван с 0.

Да, результатом оператора постинкремента является исходное значение... и затем в следующем вызове метода вы новый i, Другими словами, этот вызов:

doStuff(i++); 

эквивалентно:

int original = i;
i = original + 1;
doStuff(original);

Из раздела JLS 15.14.2:

Значением выражения приращения постфикса является значение переменной до сохранения нового значения.

Учитывая, что вы не используете i снова после этого (и, следовательно, любой побочный эффект на это бессмысленно), почему бы просто не упростить вашу жизнь?

doStuff(i + 1);

(Как и во всех параметрах в Java, вы видите передачу по значению - изменение значения i в методе не изменяется значение аргумента вызывающей стороны.)

Он ведет себя так, как и ожидалось, вы, вероятно, хотите заменить i++ с ++i,

Проверьте документацию оракула о том, как использовать унарный оператор префикса / постфикса:

class PrePostDemo {
    public static void main(String[] args){
        int i = 3;
        i++;
        // prints 4
        System.out.println(i);
        ++i;               
        // prints 5
        System.out.println(i);
        // prints 6
        System.out.println(++i);
        // prints 6
        System.out.println(i++);
        // prints 7
        System.out.println(i);
    }
}

(выдержка из связанной страницы)

++ Оператор работает так, как ожидалось. сначала он возвращает значение переменной, а затем увеличивает переменную, следовательно, вы всегда передаете 0.

Это:

doStuff(i++);

как:

int x = i;
i += 1;
doStuff(x);

i++ означает, что: "используйте значение i, а затем увеличивайте его". Это всегда будет ноль, когда передается вниз. Это тип значения, а не ссылочный тип. Если это будет объект, это не будет проблемой, потому что он будет обрабатываться как ссылка.

Другие вопросы по тегам