Suche…


Bemerkungen

Dies sollte Ihnen helfen, eine "Null-Zeiger-Ausnahme" zu verstehen - man erhält eine davon, weil eine Objektreferenz null ist, der Programmcode jedoch erwartet, dass das Programm etwas in dieser Objektreferenz verwendet. Das verdient jedoch ein eigenes Thema ...

Objektreferenzen als Methodenparameter

In diesem Thema wird das Konzept einer Objektreferenz erläutert. Es richtet sich an Menschen, die mit der Programmierung in Java noch nicht vertraut sind. Sie sollten bereits mit einigen Begriffen und Bedeutungen vertraut sein: Klassendefinition, Hauptmethode, Objektinstanz und der Aufruf von Methoden "auf" einem Objekt sowie die Übergabe von Parametern an Methoden.

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;
  }
}

Um sich mit der Java-Programmierung auskennen zu können, sollten Sie in der Lage sein, dieses Beispiel jemand anderem außerhalb Ihres Kopfes zu erklären. Ihre Konzepte sind grundlegend für das Verständnis der Funktionsweise von Java.

Wie Sie sehen können, haben wir eine main , die ein Objekt auf die Variable instanziiert person , und ruft eine Methode , die festlegen name Feld in dem Objekt zu "Bob" . Dann ruft es eine andere Methode auf und übergibt person als einen von zwei Parametern; Der andere Parameter ist eine Ganzzahlvariable, die auf 5 gesetzt ist.

Die aufgerufene Methode setzt den name des übergebenen Objekts auf "Linda" und die ganzzahlige Variable auf 99, die zurückgegeben wird.

Was würde also gedruckt werden?

Linda 5

Warum wird die Änderung der person in main wirksam, die Änderung der Ganzzahl jedoch nicht?

Wenn der Aufruf erfolgt, übergibt die Hauptmethode eine Objektreferenz für eine person an die Methode setPersonName . Jede Änderung, die setAnotherName an diesem Objekt vornimmt, ist Teil dieses Objekts. setAnotherName sind diese Änderungen immer noch Teil dieses Objekts, wenn die Methode zurückgegeben wird.

Eine andere Art, das Gleiche zu sagen: person zeigt auf ein Objekt (auf dem Haufen gespeichert, falls Sie interessiert sind). Alle Änderungen, die die Methode an diesem Objekt vornimmt, werden "an diesem Objekt" vorgenommen und haben keinen Einfluss darauf, ob die Methode, die die Änderung vornimmt, noch aktiv ist oder zurückgegeben wurde. Wenn die Methode zurückkehrt, werden alle an dem Objekt vorgenommenen Änderungen immer noch in diesem Objekt gespeichert.

Vergleichen Sie dies mit der übergebenen Ganzzahl. Da dies ein primitives int (und keine Integer-Objektinstanz) ist, wird es "by value" übergeben. Das bedeutet, dass der Wert der Methode zur Verfügung gestellt wird und kein Zeiger auf die ursprünglich übergebene Integer-Zahl. Die Methode kann sie für die Methode ändern eigene Zwecke, dies hat jedoch keine Auswirkungen auf die Variable, die beim Aufruf der Methode verwendet wird.

In Java werden alle Grundelemente nach Wert übergeben. Objekte werden als Referenz übergeben, das heißt, ein Zeiger auf das Objekt wird als Parameter an alle Methoden übergeben, die sie verwenden.

Eine weniger offensichtliche Sache bedeutet das: Eine aufgerufene Methode kann kein neues Objekt erstellen und als einen der Parameter zurückgeben. Die einzige Möglichkeit für eine Methode, ein Objekt zurückzugeben, das direkt oder indirekt durch den Methodenaufruf erstellt wird, ist der Rückgabewert der Methode. Lassen Sie uns zuerst sehen, wie das nicht funktionieren würde und dann, wie es funktionieren würde.

Fügen wir unserem kleinen Beispiel hier eine weitere Methode hinzu:

private static void getAnotherObjectNot(Person person) {
  person = new Person();
  person.setName("George");
}

Und zurück in der main , unter dem Aufruf von setAnotherName , rufen setAnotherName diese Methode und einen weiteren Aufruf von println auf:

getAnotherObjectNot(person);
System.out.println(person.getName());

Nun würde das Programm ausdrucken:

Linda 5
Linda

Was ist mit dem Objekt passiert, das George hatte? Nun, der Parameter, der übergeben wurde, war ein Zeiger auf Linda; Wenn die getAnotherObjectNot Methode ein neues Objekt erstellt hat, hat sie die Referenz auf das Linda-Objekt durch eine Referenz auf das George-Objekt ersetzt. Das Linda Objekt existiert noch (auf dem Heap), das main noch darauf zugreifen kann, aber die getAnotherObjectNot Methode wäre nicht in der Lage sein , etwas nach , dass mit ihm zu tun, weil es keinen Hinweis darauf hat. Es scheint, dass der Verfasser des Codes beabsichtigte, dass die Methode ein neues Objekt erstellt und zurückgibt, aber wenn dies der Fall war, funktionierte es nicht.

Wenn der Autor dies tun wollte, müsste er das neu erstellte Objekt aus der Methode zurückgeben, etwa wie folgt:

private static Person getAnotherObject() {
  Person person = new Person();
  person.setName("Mary");
  return person;
}

Dann nennen Sie es so:

Person mary;
mary = getAnotherObject();
System.out.println(mary.getName());

Und die gesamte Programmausgabe wäre jetzt:

Linda 5
Linda
Mary

Hier ist das gesamte Programm mit beiden Ergänzungen:

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow