Java Arraylist更改会影响其他变量

时间:2018-08-12 18:07:29

标签: java list javafx arraylist immutability

我正在使用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;
   }
}

3 个答案:

答案 0 :(得分:6)

这是因为personcancelPerson 引用 ,并且在您执行

 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的实例)是引用类型。这意味着当您执行分配时,您只是在复制对实例的引用。

在您的代码中,personcancelPerson都引用相同的Person实例,并且您对它们执行的任何操作都会影响该实例。

如果您不希望修改实例,则可以先复制Person实例。