Java类混乱

时间:2011-07-30 06:18:33

标签: java

我对Java编程很陌生,但我在c / c ++方面有一些经验,我注意到我的一些代码中有一些不需要的行为,我只是想知道如何修复它。

这就是我所拥有的:

List<State> list = new ArrayList<State>();
State cur = new State();
cur.x = 1;
cur.y = 1;
list.add(cur);
cur.x = 2;
cur.y = 3;
list.add(cur);
cur.x = 3;
cur.y = 4;
list.add(cur);
for (State i : list)
    System.out.println(i.x + " " + i.y);


class State
{
    public int x = 0;
    public int y = 0;
}

这给了我一个输出: 3 4 3 4 3 4

我希望输出在哪里: 1 1 2 3 3 4

我该如何解决这个问题? 谢谢, paintstripper

4 个答案:

答案 0 :(得分:2)

在C ++中,您可能希望此List.add()函数使用复制构造函数,但在Java中,所有对象(即非基本类型)本质上都是引用。这意味着在您将cur添加到列表后,您将在其中添加对它的引用。然后,您将通过cur引用修改以下值,以便它们全部为3和4。

要解决您的问题,您应该使用不同的State对象并单独添加它们。

编辑:只是为了在这里添加更多信息,Java总是按值。但是,当您将对象传递给函数时,由于该对象本质上是一个引用,因此引用将按值传递。这意味着虽然您可以修改函数内部的原始对象,但是如果为该函数内部的引用分配新内容(例如交换具有临时值的两个对象),它将无效。

答案 1 :(得分:2)

您只有一个对象,但是在列表中添加了3个不同的引用,同时更改了它的状态(x和y)。所以最后它的x是3,y是4。

您可能想要添加不同的对象。所以:

List<State> list = new ArrayList<State>();
State cur = new State();
cur.x = 1;
cur.y = 1;
list.add(cur);
cur = new State();
cur.x = 2;
cur.y = 3;
list.add(cur);
cur = new State();
cur.x = 3;
cur.y = 4;
list.add(cur);
for (State i : list)
    System.out.println(i.x + " " + i.y);


class State
{
    public int x = 0;
    public int y = 0;
}

答案 2 :(得分:1)

很简单,在每个list.add()之后执行一个cur = new State(),以便在'cur'中获得一个新的State实例。你正在做的是将相同的实例添加到列表中,如果在cur中使用State的指针或引用,这与C ++没有什么不同。

答案 3 :(得分:1)

你遇到的问题是你正在改变一个对象。最好避免公开可变的成员变量。如果您按如下所示编写State类,则无法进行编程错误。

List<State> list = new ArrayList<State>();
State cur = new State(1,1);
list.add(cur);
cur = new State(2,3);
list.add(cur);
cur = new State(3,4);
list.add(cur);
for (State i : list)
    System.out.println(i.x + " " + i.y);


class State
{
    public final int x;
    public final int y;

    public State(int x, int y) 
    {
        this.x = x;
        this.y = y;
    }

}

注意x和y成员上的final关键字,这意味着它们在构造之后无法分配。