anu*_*ith 3 java javafx list arraylist immutability
我正在使用java fx,在下面的代码中没什么好看的,并且捕获文本字段的focusedProperty来覆盖下面新输入的值.下面的代码更改了在文本字段中输入的人名,当用户单击取消按钮时,它会将旧名称放回文本字段.但由于某些原因,一个魔法发生了,每当我设置这个人的名字时,它会覆盖cancelPerson变量中的字段.无法弄清楚为什么会这样?在设置新值之前,我从人员列表中获取cancelPerson.那么人员名单中的变化怎么会影响一个自变量.知道为什么会这样吗?谢谢.
private ObservableList<Person> persons;
private Person person;
private Person cancelPerson;
personName.focusedProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue) {
final int index = personIdCombo.getSelectionModel().getSelectedIndex();
cancelPerson = persons.get(index);
final Person person = persons.get(index);
person.setName(personName.getText());
persons.set(index, person);
}
}
);
class Person{
private final StringProperty name;
public Person() {
this.name = new SimpleStringProperty("testName");
}
public SystemParams(Person person) {
this.name = person.name;
}
}
Run Code Online (Sandbox Code Playgroud)
这是因为person并且cancelPerson是参考,当你这样做
cancelPerson = persons.get(index);
final Person person = persons.get(index);
Run Code Online (Sandbox Code Playgroud)
最终,两个变量都指向同一个对象.
如果要保存副本,person则必须执行"深层复制",即创建新的Person并将内容复制到新对象.这通常使用所谓的"复制构造函数"来完成
class Person {
public Person() { ... the no-arg constructor }
public Person(Person p) {
this.name = p.name;
... etc
}
}
Run Code Online (Sandbox Code Playgroud)
吉姆·加里森(Jim Garrison)的答案(建议复制构造函数)是正确的。我只是想添加另一个答案,以提供一种有用的方式来思考Java中的引用。
我发现将=作业视为REFERS TO作业很有帮助。所以,cancelPersons = persons.get(index);基本上是说:
cancelPerson REFERS TO persons.get(index);
Run Code Online (Sandbox Code Playgroud)
现在,第二行显示final Person person = persons.get(index);,将其视为
final Person person REFERS TO persons.get(index);
看到他们两个如何引用相同persons.get(index)?现在,无论您使用cancelPerson还是person,Java都指向相同的总体对象,而不是不同的对象。
除非您在new某个地方有关键字,否则您实际上并不是在创建新对象。