После вызова a всё ещё указывает на объект №1: instanceNumber = 1, x = 12, y = 22, z = 3. Присваивание нового A локальному параметру не заменяет ссылку вызывающего метода.
Влияние методов на поля экземпляра и статические переменные
После вызова a всё ещё указывает на объект №1: instanceNumber = 1, x = 12, y = 22, z = 3. Присваивание нового A локальному параметру не заменяет ссылку вызывающего метода.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Дан класс, содержащий статическое поле, поле, объявленное как final, обычное поле экземпляра и метод doIt, который меняет значения этих полей и создаёт новый объект. В main создаётся объект, вызывается doIt, после чего нужно определить, какие значения будут у переменных.
public class A {
private static int y;
private final int instanceNumber;
private int x;
public A(int instanceNumber) {
this.instanceNumber = instanceNumber;
}
public String toString() {
return String.valueOf(instanceNumber);
}
private static void doIt(int i, A a) {
i = 11;
a.x = 12;
a.y = 13;
a = new A(2); // новый объект
a.x = 21;
a.y = 22;
}
public static void main(String[] args) {
A a = new A(1); // создаём объект с instanceNumber = 1
a.x = 1;
a.y = 2;
int z = 3;
A.doIt(z, a); // вызываем метод
// Вопросы:
// a = ? // 1 или 2
// a.instanceNumber = ?
// a.x = ?
// a.y = ?
// z = ?
}
}
Ответ
После вызова a всё ещё указывает на объект №1: instanceNumber = 1, x = 12, y = 22, z = 3. Присваивание нового A локальному параметру не заменяет ссылку вызывающего метода.
Java передаёт аргументы по значению. Копия ссылки a сначала указывает на тот же объект, поэтому a.x = 12 виден снаружи. После a = new A(2) изменения x относятся уже ко второму объекту. Поле y статическое и общее для обоих экземпляров: последняя запись задаёт 22. Число i — независимая копия z, поэтому z остаётся 3. Для ясности к статическому полю следует обращаться как A.y, а не через экземпляр.