#java
#java
Вопрос:
public class Person {
private String name;
private int birthYear;
public Person(String name) {
this.name = name;
this.birthYear = 1970;
}
public int getBirthYear() {
return this.birthYear;
}
public void setBirthYear(int birthYear) {
this.birthYear = birthYear;
}
public String toString() {
return this.name " (" this.birthYear ")";
}
}
public class Example {
public static void main(String[] args) {
Person first = new Person("First");
System.out.println(first);
youthen(first);
System.out.println(first);
Person second = first;
youthen(second);
System.out.println(first);
}
public static void youthen(Person person) {
person.setBirthYear(person.getBirthYear() 1);
}
}
В моем руководстве говорится, что результат будет:
First (1970)
First (1971)
First (1972)
Я могу следить за кодом до тех пор, пока не будет создан объект второго лица. Тогда я не понимаю, почему вызов метода youthen для объекта второго лица изменяет объект первого лица.
На мой взгляд, есть два объекта Person. Мы изменили год рождения Person first , затем скопировали значения переменных экземпляра Person first в Person second, а затем обработали значения переменных экземпляра Person second, используя метод youthen, в то время как Person first не изменился с момента предыдущего вызова метода. Я ожидал, что окончательный метод печати вернет
First (1971)
Комментарии:
1. Потому что second имеет ту же ссылку в памяти, что и first
Ответ №1:
до тех пор, пока не будет создан объект второго лица
Нет. Этот код создает только один Person
объект. Прямо здесь:
new Person("First")
Ни в какой другой точке Person
конструктор не вызывается, поэтому ни в какой другой точке не создается другой Person
объект. У вас есть несколько ссылок на один и тот же Person
объект:
Person second = first;
В качестве аналогии представьте, что у вас есть дом, и вы записываете адрес этого дома на двух листках бумаги. Один человек, используя свой листок бумаги, идет в дом и что-то в нем меняет. (Например, окрашивает его в новый цвет.) Затем второй человек использует свой листок бумаги, чтобы подойти к дому, и видит новый цвет. Потому что есть только один дом, независимо от того, сколько людей знают его адрес.
Чтобы создать второй Person
, повторно вызовите конструктор:
Person second = new Person("Second");
Комментарии:
1. Мне очень нравится аналогия между домом и адресом, спасибо!
2. Спасибо! Мне пришло в голову, что никогда не было нового оператора Person, поэтому второй объект не был создан. Это имеет смысл. Так что теперь я просто не понимаю, в чем смысл всего этого. Почему бы просто не вызвать youthen(сначала)? Можете ли вы привести мне реальный пример кода, в котором добавление второй ссылки на тот же объект решает проблему?
3. @gfries: Одним из примеров может быть ваш собственный
youthen()
метод. Если новая ссылка на тот же объект не была создана, а вместо нее был создан совершенно новый объект, этот метод ничего не сделает. Егоperson
переменной будет новый объект. Он установит значение для этого нового объекта, а затем вернет его, не внося никаких изменений в исходный объект. Или когда вы вызываете методы дляPerson
самого себя, на что будетthis
ссылаться, если не на тот же объект, что и переменная, для которой вы вызвали метод? Тихое дублирование объектов будет иметь серьезные последствия, нанося ущерб языку.