Java Arraylist更改会影响其他变量

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)

Jim*_*son 5

这是因为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)


Zep*_*hyr 5

吉姆·加里森(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某个地方有关键字,否则您实际上并不是在创建新对象。