Reputation: 167
I am using java fx, nothing fancy in the code below, and catching the text field's focusedProperty to overwrite the newly entered value below. The code below changes a person's name that is entered in the textfield and when user clicks on cancel button it will put the old name back into the textfield. But for some reason a magic happens and whenever I set the person's name it overwrites the field in the cancelPerson variable. Could not figure out why this would happen? I get the cancelPerson from persons list before I set the new value. So how come changes in the persons list can affect an independent variable. Any idea why this would occur? Thanks.
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;
}
}
Upvotes: 3
Views: 1027
Reputation: 10253
Jim Garrison's answer (suggesting the copy constructor) is correct; I just wanted to add another answer to give a helpful way of thinking about references in Java.
I found it helpful to think of an =
assignment as a REFERS TO
assignment. So, cancelPersons = persons.get(index);
is basically saying:
cancelPerson REFERS TO persons.get(index);
Now, where your second line says final Person person = persons.get(index);
, think of it as
final Person person REFERS TO persons.get(index);
See how they both REFER TO the same persons.get(index)
? Now, whether you use cancelPerson
or just person
, Java is pointing back to the same overall object, not different ones.
Unless you have a new
keyword somewhere, you are not actually creating a new object.
Upvotes: 6
Reputation: 4774
In Java, class instances like instances of Person
are reference types. This means that when you perform an assignment, you are merely copying a reference to an instance.
In your code, person
and cancelPerson
both refer to the same Person instance and any operations you do on them affect that same instance.
You could make a copy of a Person
instance first if you don't want it to be modified.
Upvotes: 2
Reputation: 86774
This is because person
and cancelPerson
are references and when you do
cancelPerson = persons.get(index);
final Person person = persons.get(index);
You end up with both variables pointing to the same object.
If you want to save a copy of person
you have to do a "deep copy", that is create a new Person
and copy the contents to the new object. This is usually done with what is referred to as a "copy constructor"
class Person {
public Person() { ... the no-arg constructor }
public Person(Person p) {
this.name = p.name;
... etc
}
}
Upvotes: 5