循环中的Java“pass-by-value”

时间:2014-09-10 11:48:14

标签: java

我认为这个问题与这个问题有关: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是一个更复杂的类)?

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

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

类似的东西:

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

否则,每次都会引用相同的实例。

因此,set调用会修改相同的Calendar,这就是您获得所有9的原因。

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

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

答案 2 :(得分:0)

class Main

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

}

class foo {     私人日历mCal;

public foo(Calendar cal) {
    mCal = cal;
}

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

}

您正在覆盖您的日历对象