Sök…


Anmärkningar

Detta skulle hjälpa dig att förstå ett "Null Pointer Exception" - en får en av dem eftersom en objektreferens är noll, men programkoden förväntar sig att programmet ska använda något i objektreferensen. Men det förtjänar sitt eget ämne ...

Objektreferenser som metodparametrar

Detta ämne förklarar begreppet objektreferens ; den riktar sig till personer som är nya i att programmera i Java. Du bör redan vara bekant med vissa termer och betydelser: klassdefinition, huvudmetod, objektinstans och anrop av metoder "på" ett objekt och överföra parametrar till metoder.

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

För att vara helt kompetent i Java-programmering bör du kunna förklara det här exemplet till någon annan längst upp i huvudet. Dess koncept är grundläggande för att förstå hur Java fungerar.

Som ni ser har vi en main som instansierar en objekt till variabeln person , och efterlyser en metod för att ställa in name fältet i objektet till "Bob" . Sedan kallar det en annan metod, och passerar person som en av två parametrar; den andra parametern är en heltalvariabel, inställd på 5.

Den metod som kallas sätter name värde på passerat objektet till "Linda', samt satser den heltalsvariabel som skickas till 99, sen åter.

Så vad skulle tryckas?

Linda 5

Så varför träder den förändring som görs i person i main , men ändringen av heltalet gör det inte?

När samtalet sker passerar setPersonName en objektreferens för person till metoden setPersonName ; alla ändringar som setAnotherName gör till det objektet är en del av det objektet, och därför är dessa ändringar fortfarande del av det objektet när metoden återgår.

Ett annat sätt att säga samma sak: person pekar på ett objekt (lagrat på högen, om du är intresserad). Alla ändringar som metoden gör till det objektet görs "på det objektet" och påverkas inte av om metoden som gör ändringen fortfarande är aktiv eller har återvänt. När metoden återgår lagras eventuella ändringar i objektet fortfarande på det objektet.

Kontrast detta med heltalet som passeras. Eftersom detta är ett primitivt int (och inte ett heltalsobjektinstans), skickas det "av värde", vilket innebär att dess värde tillhandahålls till metoden, inte en pekare till det ursprungliga heltalet som skickats in. Metoden kan ändra det för metodens egna syften, men det påverkar inte den variabel som används när metodsamtalet görs.

I Java skickas alla primitiv efter värde. Objekt passeras genom referens, vilket innebär att en pekare till objektet skickas som parameter till alla metoder som tar dem.

En mindre uppenbar sak betyder detta: det är inte möjligt för en kallad metod att skapa ett nytt objekt och returnera det som en av parametrarna. Det enda sättet för en metod att returnera ett objekt som skapas, direkt eller indirekt, av metodsamtalet, är som ett returvärde från metoden. Låt oss först se hur det inte skulle fungera, och sedan hur det skulle fungera.

Låt oss lägga till en annan metod till vårt lilla exempel här:

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

Och tillbaka i main , under samtalet till setAnotherName , låt oss ringa ett samtal till den här metoden och ett annat tryckt samtal:

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

Nu skulle programmet skriva ut:

Linda 5
Linda

Vad hände med föremålet som hade George? Tja, parametern som skickades in var en pekare till Linda; när metoden getAnotherObjectNot skapade ett nytt objekt, ersatte den referensen till Linda-objektet med en referens till George-objektet. Linda objektet finns stilla (på högen), den main metoden kan fortfarande komma åt det, men getAnotherObjectNot metod skulle inte kunna göra något med det efter det, eftersom den inte har någon referens till den. Det verkar som att författaren till koden avsedd för metoden att skapa ett nytt objekt och skicka tillbaka det, men i så fall fungerade det inte.

Om det är vad författaren ville göra, skulle han behöva lämna tillbaka det nyskapade objektet från metoden, något liknande:

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

Ring det så här:

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

Och hela programutgången skulle nu vara:

Linda 5
Linda
Mary

Här är hela programmet, med båda tillägg:

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow