【问题标题】:Java post-increment (++) not behaving as expected when passed as a parameter作为参数传递时,Java 后增量 (++) 的行为不符合预期
【发布时间】:2012-10-03 07:52:45
【问题描述】:

我遇到了以下问题:

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

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

我希望这会运行 doStuff 10 次然后返回。

但是,i++ 在使用 0 再次调用 doStuff 之前不会被执行。

结果是一个无限循环。我知道如何修复它,但我想知道这种行为是正确的还是错误。

【问题讨论】:

  • 使用后增量时的预期行为
  • ...如果你改用doStuff(++i),你会得到你所期望的。

标签: java post-increment pre-increment


【解决方案1】:

现在我希望它运行 doStuff 10 次然后返回,但是在使用 0 再次调用 doStuff 之前 i++ 不会执行。

是的,后自增运算符的结果是原始值……然后在下一次调用该方法时,您将获得一个新的i。换句话说,这个调用:

doStuff(i++); 

相当于:

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

来自JLS section 15.14.2

后缀增量表达式的值是变量之前存储新值之前的值。

鉴于您以后不再使用i(因此任何副作用都是没有意义的),为什么不简化您的生活?

doStuff(i + 1);

(与 Java 中的 all 参数一样,您看到的是按值传递 - 在方法中更改 i 的值不会更改值调用者的论点。)

【讨论】:

  • +1 或 doStuff(++i); 可以,但不是很好的选择。
  • 为什么i + 1++i 更好?可读性?
  • @DavidGrant:是的——你不需要考虑任何排序。 i 的值的副作用是没有意义的,那么为什么还要费心呢?
  • @JonSkeet 为什么确实如此。谢谢。
  • @JonSkeet“通过引用”?您是否打算说“按值传递”?
【解决方案2】:

它的行为与 预期的一样,你可能想用 ++i 替换 i++

查看oracle documentation 了解如何使用前缀/后缀一元递增运算符:

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);
    }
}

(摘自链接页面)

【讨论】:

  • 正如我所写,我知道如何修复它,就像你指出的 ++i 一样,但我有点惊讶。我本来希望它先执行操作,然后再拨打电话。
  • @dngfng:它在调用之前递增i,但调用的参数i的原始值。
  • @JonSkeet,确实……我刚刚修好了。 :-)
【解决方案3】:

i++ 表示:“使用 i 的值,然后递增它”。传递时它总是为零。它是值类型,而不是引用类型。如果那是一个对象,那没有问题,因为它会被当作参考来处理。

【讨论】:

    【解决方案4】:

    ++ 运算符按预期工作。它首先返回变量的值,然后增加变量,因此你总是传递 0。

    这个:

    doStuff(i++);
    

    就像:

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

    【讨论】:

      猜你喜欢
      • 2020-08-20
      • 2021-04-09
      • 2016-11-06
      • 2015-05-03
      相关资源
      最近更新 更多