Java Arraylist更改会影响其他变量

Java Arraylist更改会影响其他变量,java,list,javafx,arraylist,immutability,Java,List,Javafx,Arraylist,Immutability,我正在使用JavaFX,下面的代码中没有什么特别之处,我捕获文本字段的focusedProperty来覆盖下面新输入的值。下面的代码更改了在文本字段中输入的姓名,当用户单击“取消”按钮时,它会将旧姓名放回文本字段。但是由于某种原因,一个神奇的事情发生了,每当我设置这个人的名字时,它就会覆盖cancelPerson变量中的字段。不知道为什么会发生这种情况?在设置新值之前,我从人员列表中获取cancelPerson。那么,为什么人员列表中的变化会影响一个自变量呢。你知道为什么会这样吗?谢谢 pri

我正在使用JavaFX,下面的代码中没有什么特别之处,我捕获文本字段的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;
   }
}
私人观察者;
私人;
私人;
personName.focusedProperty().addListener((可观察、旧值、新值)->{
如果(!newValue){
final int index=personidcompo.getSelectionModel().getSelectedIndex();
cancelPerson=persons.get(索引);
最终人员=人员.get(索引);
person.setName(personName.getText());
persons.set(索引,person);
}
}
);
班主任{
私有财产名称;
公众人士(){
this.name=新的SimpleStringProperty(“testName”);
}
公共系统参数(个人){
this.name=person.name;
}
}

这是因为
person
cancelPerson
都是参考,当您这样做时

 cancelPerson = persons.get(index);
 final Person person = persons.get(index);
最后两个变量都指向同一个对象

如果要保存
person
的副本,必须进行“深度复制”,即创建一个新的
person
,并将内容复制到新对象。这通常是通过所谓的“复制构造函数”来完成的


在Java中,类实例(如
Person
的实例)是引用类型。这意味着,当您执行赋值时,您只是将引用复制到实例

在您的代码中,
person
cancelPerson
都引用同一个人实例,您对它们执行的任何操作都会影响该实例

如果不想修改
个人
实例,可以先复制该实例

Jim Garrison的回答(暗示复制构造函数)是正确的;我 只是想添加另一个答案,提供一种有用的思考方式 关于Java中的引用

我发现将
=
作业视为
指的是
作业是有帮助的。所以,
cancelPersons=persons.get(index)基本上是说:

cancelPerson REFERS TO persons.get(index);
现在,您的第二行显示
final Person=persons.get(index),将其视为

最终的Person是指persons.get(索引)

查看它们如何引用相同的
人员。获取(索引)
?现在,无论您使用
cancelPerson
还是仅使用
person
,Java都指向相同的整体对象,而不是不同的对象


除非您在某处有一个
新的
关键字,否则您实际上并不是在创建一个新对象。

谢谢您的回答。我创建了副本const。他做到了这一点。cancelPerson=新人员(persons.get(index));这仍然会对被取消者产生同样的影响。我做错什么了吗?你需要共享你为我们编写的构造函数的代码来帮助我们解决这个错误…我添加了我的类的一小部分。谢谢你的帮助
cancelPerson REFERS TO persons.get(index);