ArrayList的Java数组 - 奇怪的事情?

时间:2011-08-03 18:45:05

标签: java

我一整天都在拉着头发。可能是某种类型的新错误,但我无法理解它。

它开始变得更复杂,但我把它简化为:

public class Main {

    static ArrayList<Selection>[] a = new ArrayList[2];

    public static void main(String[] args) {

        // Initialise the Selection ArrayList

        for (int i=0; i < a.length; i++) {
            a[i] = new ArrayList<Selection>();
        }

        callTest();

    }

    public static void callTest () {

        a[0].add(new Selection(true));
        a[1].add(new Selection(false));

        System.out.println(a[0].get(0).getTF());
        System.out.println(a[1].get(0).getTF());
    }
}

class Selection {

    private static boolean trueFalse;

    public Selection (boolean iTF) {
        trueFalse = iTF;
    }

    public boolean getTF () {
        return trueFalse;
    }
}

运行程序将返回:

false
false

而不是预期的(至少对我来说):

true
false

有人可以对此有所了解吗?看起来每当更改Selection对象中保存的值时,即使它们具有不同的对象引用,也会更改所有Selection对象。我做过傻事吗?

5 个答案:

答案 0 :(得分:17)

这是因为truefalse是静态的,是类的一部分而不是对象的一部分。因此,对于所有Selection对象,只有一个truefalse值,并且每次调用构造函数时它都会被更改。您将要删除静态修改器,然后所有应该按计划工作!

为了避免将来出现这样的问题,至少在开始时不要像这样宣布静态的东西时最好 - 尽可能保留对象,即使你知道自己只创建了一个!这将使您获得良好的OO思维模式,并减少这些类型的问题。当然,有些地方你需要使用它,这是正确的做法,但你会随着时间的推移学到这一点。

答案 1 :(得分:8)

这是因为在Selection中您将trueFalse声明为静态变量。只需将其更改为:

class Selection {

    //one per Selection, versus a global variable
    private boolean trueFalse;

    public Selection (boolean iTF) {
        trueFalse = iTF;
    }

}

答案 2 :(得分:4)

更改

private static boolean trueFalse;

private boolean trueFalse;

那应该解决它。基本上,因为trueFalse是静态的,它由Selection类的每个实例共享。

答案 3 :(得分:4)

在课程Selection中,您已将trueFalse声明为静态。这意味着它是类的一部分,而不是实例的一部分,因此它被所有实例共享。

答案 4 :(得分:4)

来自The Java Tutorials

  • 类变量(静态字段)类变量是使用static修饰符声明的任何字段;这告诉编译器这个变量只有一个副本存在,无论该类被实例化多少次。

这绝对是一个“newb”错误。