我对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
答案 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关键字,这意味着它们在构造之后无法分配。