【问题标题】:Java "pass-by-value" in a loop循环中的Java“按值传递”
【发布时间】:2014-09-10 11:48:13
【问题描述】:

我认为这个问题与这个问题有关:Is Java "pass-by-reference" or "pass-by-value"?,但并不完全相同。

假设我有这个循环代码:

ArrayList<foo> list = new ArrayList<foo>();
Calendar cal = Calendar.getInstance();
for(int i = 0; i < 10; ++i) {
    cal.set(Calendar.HOUR, i);
    list.add(new foo(cal));
}
for(int i = 0; i < 10; ++i) {
    System.out.print(list.get(i).calToString());
}

foo.class:

public class foo {
    private Calendar mCal;
    public foo(Calendar cal) {
        mCal = cal;
    }
    public String calToString() {
        return String.valueOf(mCal.get(Calendar.HOUR));
    }
}

结果列表将其所有项目 Calendar.HOUR 设置为 9。它打印9999999999。我怎样才能使每个项目分别有0-9?在循环内实例化变量cal 是否会成为性能问题(如果foo 是一个更复杂的类)?

【问题讨论】:

标签: java


【解决方案1】:

实际上你正在覆盖你的对象,你在循环之外声明它并且你不断改变它的值。

您应该在循环内创建 new 实例。不,您不会注意到任何性能问题。

【讨论】:

  • 好的,我在循环内实例化了 Calendar 变量,但仍将声明保留在外部,然后它给出了 0-9 的列表项。但是在内存分配方面,在循环外声明变量与在循环内声明变量有何不同?
  • 在内存分配方面,在第一种情况下,您只为一个对象分配内存并在每次迭代时覆盖它。在第二种情况下(我的回答),您每次都创建一个新对象。
  • 我的意思是声明。我做了你所说的并在循环内实例化,但我将声明保留在外面。如果我也在循环内移动声明有什么区别?
  • 没有什么不同,编译器会优化它。字节码将是相同的。
  • 但请注意,在循环之外声明它更清楚。
【解决方案2】:

您需要为循环的每次迭代初始化一个新的Calendar

类似:

for(int i = 0; i < 10; ++i) {
    Calendar cal = Calendar.getInstance();

否则,每次都会引用同一个实例。

因此,set 调用修改了相同的 Calendar,这就是为什么您会得到所有 9s。

也许更优雅的是,您可以使用构造函数初始化您的Foo 类,该构造函数占用实际小时int

然后您将更改 Foo 以拥有自己的 Calendar 实例。

【讨论】:

    【解决方案3】:

    主类

    { public static void main(String[] args) {

        ArrayList<foo> list = new ArrayList<foo>();
        Calendar cal = null;
        for (int i = 0; i < 10; ++i) {
            cal=Calendar.getInstance();
            cal.set(Calendar.HOUR, i);
            list.add(new foo(cal));
        }
        for (int i = 0; i < 10; ++i) {
            System.out.print(list.get(i).calToString());
        }
    }
    

    }

    类 foo { 私人日历 mCal;

    public foo(Calendar cal) {
        mCal = cal;
    }
    
    public String calToString() {
        return String.valueOf(mCal.get(Calendar.HOUR));
    }
    

    }

    你正在覆盖你的日历对象

    【讨论】:

      猜你喜欢
      • 2021-11-04
      • 1970-01-01
      • 2014-09-10
      • 2016-03-15
      • 1970-01-01
      • 2016-11-28
      相关资源
      最近更新 更多