Поиск…


замечания

Это должно помочь вам понять «Исключение 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;
  }
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow