Java Language
Ссылки на объекты
Поиск…
замечания
Это должно помочь вам понять «Исключение Null Pointer» - один получает один из них, потому что ссылка на объект имеет значение null, но программный код ожидает, что программа что-то использует в этой ссылке на объект. Тем не менее, это заслуживает своей темы ...
Ссылки на объекты как параметры метода
В этом разделе объясняется концепция ссылки на объект ; он ориентирован на людей, которые новичок в программировании на Java. Вы уже должны быть знакомы с некоторыми терминами и значениями: определение класса, основной метод, экземпляр объекта и вызов методов «на» объекта и передача параметров методам.
public class Person {
private String name;
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public static void main(String [] arguments) {
Person person = new Person();
person.setName("Bob");
int i = 5;
setPersonName(person, i);
System.out.println(person.getName() + " " + i);
}
private static void setPersonName(Person person, int num) {
person.setName("Linda");
num = 99;
}
}
Чтобы быть полностью компетентным в программировании на Java, вы должны уметь объяснить этот пример кому-то еще с головы. Его концепции имеют фундаментальное значение для понимания того, как работает Java.
Как вы можете видеть, у нас есть main
задача, которая создает объект для person
переменной и вызывает метод для установки поля name
в этом объекте на "Bob"
. Затем он вызывает другой метод и передает person
как один из двух параметров; другой параметр представляет собой целочисленную переменную, установленную в 5.
Метод , называемый задает name
значение на пройденный объекта к «Линде», и устанавливает целочисленную переменную передается до 99, а затем возвращается.
Так что будет печататься?
Linda 5
Итак, почему внесение изменений в person
вступает в силу в main
, но изменение, внесенное в целое число, не так ли?
Когда вызов выполняется, основной метод передает ссылку объекта для person
методу setPersonName
; любое изменение, которое setAnotherName
делает для этого объекта, является частью этого объекта, и поэтому эти изменения остаются частью этого объекта при возврате метода.
Другой способ сказать одно и то же: person
указывает на объект (хранится в куче, если вам интересно). Любое изменение метода делает для этого объекта «на этом объекте» и не зависит от того, активен или вернулся метод внесения изменения. Когда метод возвращается, любые изменения, внесенные в объект, все еще сохраняются на этом объекте.
Сравните это с целым числом, которое передается. Поскольку это примитивный int (а не экземпляр объекта Integer), он передается «по значению», то есть его значение предоставляется методу, а не указателю на исходное целое число, переданное в. Метод может изменить его для метода собственных целей, но это не влияет на переменную, используемую при вызове метода.
В Java все примитивы передаются по значению. Объекты передаются по ссылке, что означает, что указатель на объект передается как параметр любым методам, которые их принимают.
Еще одна очевидная вещь: это означает, что вызываемый метод не может создать новый объект и вернуть его в качестве одного из параметров. Единственный способ для метода вернуть объект, который создается, прямо или косвенно, вызовом метода, является возвращаемым значением из метода. Давайте сначала посмотрим, как это не сработает, и как это будет работать.
Давайте добавим еще один способ к нашему маленькому примеру:
private static void getAnotherObjectNot(Person person) {
person = new Person();
person.setName("George");
}
И, вернувшись в main
, под вызовом setAnotherName
, давайте перейдем к этому методу и другому вызову println:
getAnotherObjectNot(person);
System.out.println(person.getName());
Теперь программа распечатает:
Linda 5
Linda
Что случилось с объектом, в котором был Джордж? Ну, параметр, который был передан, был указателем на Линду; когда метод getAnotherObjectNot
создал новый объект, он заменил ссылку на объект Linda ссылкой на объект George. Объект Линда все еще существует (в куче), main
метод все равно может получить к нему доступ, но метод getAnotherObjectNot
после этого не сможет ничего с ним сделать, потому что он не имеет к нему ссылки. Похоже, что автор кода, предназначенный для метода, создавал новый объект и передавал его обратно, но если это так, это не сработало.
Если это то, что хотел сделать автор, ему нужно было бы вернуть вновь созданный объект из метода, примерно так:
private static Person getAnotherObject() {
Person person = new Person();
person.setName("Mary");
return person;
}
Затем назовите его так:
Person mary;
mary = getAnotherObject();
System.out.println(mary.getName());
И весь выпуск программы теперь будет:
Linda 5
Linda
Mary
Вот и вся программа с двумя дополнениями:
public class Person {
private String name;
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public static void main(String [] arguments) {
Person person = new Person();
person.setName("Bob");
int i = 5;
setPersonName(person, i);
System.out.println(person.getName() + " " + i);
getAnotherObjectNot(person);
System.out.println(person.getName());
Person person;
person = getAnotherObject();
System.out.println(person.getName());
}
private static void setPersonName(Person person, int num) {
person.setName("Linda");
num = 99;
}
private static void getAnotherObjectNot(Person person) {
person = new Person();
person.setMyName("George");
}
private static person getAnotherObject() {
Person person = new Person();
person.setMyName("Mary");
return person;
}
}