我正在使用java fx,下面的代码中没有花哨的内容,并且捕获了文本字段的focusProperty来覆盖下面新输入的值。下面的代码更改了在文本字段中输入的人员姓名,当用户单击“取消”按钮时,它将把旧名称重新输入到文本字段中。但是由于某种原因,魔术会发生,每当我设置人员的姓名时,它就会覆盖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;
}
}
答案 0 :(得分:6)
这是因为person
和cancelPerson
是 引用 ,并且在您执行
cancelPerson = persons.get(index);
final Person person = persons.get(index);
最后,两个变量都指向同一对象。
如果要保存person
的副本,则必须执行“深层副本”,即创建一个新的Person
并将内容复制到新对象。通常使用所谓的“复制构造函数”完成此操作
class Person {
public Person() { ... the no-arg constructor }
public Person(Person p) {
this.name = p.name;
... etc
}
}
答案 1 :(得分:4)
Jim Garrison的答案(建议复制构造函数)是正确的;一世 只是想添加另一个答案以提供有用的思维方式 关于Java中的引用。
我发现将=
分配视为REFERS TO
分配是有帮助的。因此,cancelPersons = persons.get(index);
基本上是在说:
cancelPerson REFERS TO persons.get(index);
现在,第二行显示final Person person = persons.get(index);
时,将其视为
final Person person REFERS TO persons.get(index);
看看他们两个如何参考同一个persons.get(index)
?现在,无论您使用cancelPerson
还是仅使用person
,Java都指向相同的总体对象,而不是不同的对象。
除非您在某个地方有一个new
关键字,否则您实际上并不是在创建新对象。
答案 2 :(得分:1)
在Java中,类实例(例如Person
的实例)是引用类型。这意味着当您执行分配时,您只是在复制对实例的引用。
在您的代码中,person
和cancelPerson
都引用相同的Person实例,并且您对它们执行的任何操作都会影响该实例。
如果您不希望修改实例,则可以先复制Person
实例。