Java Language
Object referenties
Zoeken…
Opmerkingen
Dit zou je moeten helpen een "Null Pointer Exception" te begrijpen - je krijgt er een omdat een objectverwijzing null is, maar de programmacode verwacht dat het programma iets in die objectverwijzing gebruikt. Dat verdient echter een eigen onderwerp ...
Objectverwijzingen als methodeparameters
In dit onderwerp wordt het concept van een objectverwijzing uitgelegd; het is gericht op mensen die nog maar net in Java programmeren. Je zou al bekend moeten zijn met enkele termen en betekenissen: klassedefinitie, hoofdmethode, objectinstantie en het aanroepen van methoden op een object en het doorgeven van parameters aan 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;
}
}
Om volledig bekwaam te zijn in het programmeren van Java, moet u dit voorbeeld aan iemand anders uit uw hoofd kunnen uitleggen. De concepten zijn fundamenteel om te begrijpen hoe Java werkt.
Zoals u kunt zien, hebben we een main
dat een object aan de variabele instantie van person
, en roept een methode om de set name
veld in dat object aan "Bob"
. Vervolgens roept het een andere methode aan en geeft deze person
als een van de twee parameters; de andere parameter is een integer variabele, ingesteld op 5.
De methode genaamd stelt de name
waarde op de doorgegeven object "Linda, en stelt de integervariabele doorgegeven aan 99, dan terug.
Dus wat zou er worden afgedrukt?
Linda 5
Dus waarom wordt de wijziging die in de person
wordt aangebracht in de main
kracht, maar de wijziging in het gehele getal niet?
Wanneer de oproep wordt gedaan, geeft de setPersonName
een objectverwijzing voor person
aan de methode setPersonName
; elke wijziging die setAnotherName
in dat object setAnotherName
maakt deel uit van dat object, en dus maken die wijzigingen nog steeds deel uit van dat object wanneer de methode terugkeert.
Een andere manier om hetzelfde te zeggen: person
wijst naar een object (opgeslagen op de heap, als je geïnteresseerd bent). Elke wijziging die de methode in dat object aanbrengt, wordt "op dat object" aangebracht en wordt niet beïnvloed door het feit of de methode die de wijziging aanbrengt nog steeds actief is of is teruggekeerd. Wanneer de methode terugkeert, worden wijzigingen die aan het object zijn aangebracht, nog steeds in dat object opgeslagen.
Vergelijk dit met het gehele getal dat wordt doorgegeven. Aangezien dit een primitieve int is (en geen instantie van een Integer-object), wordt het "door waarde" doorgegeven, wat betekent dat de waarde ervan aan de methode wordt doorgegeven, geen verwijzing naar het oorspronkelijke doorgegeven gehele getal. De methode kan deze wijzigen voor de methode eigen doeleinden, maar dat heeft geen invloed op de variabele die wordt gebruikt wanneer de methode wordt aangeroepen.
In Java worden alle primitieven doorgegeven aan waarde. Objecten worden doorgegeven door verwijzing, wat betekent dat een aanwijzer naar het object wordt doorgegeven als de parameter voor alle methoden die ze gebruiken.
Een minder voor de hand liggend ding betekent dit: het is niet mogelijk voor een aangeroepen methode om een nieuw object te maken en terug te geven als een van de parameters. De enige manier voor een methode om een object te retourneren dat direct of indirect door de methode-aanroep is gemaakt, is als een retourwaarde van de methode. Laten we eerst kijken hoe dat niet zou werken en dan hoe het zou werken.
Laten we hier nog een methode toevoegen aan ons kleine voorbeeld:
private static void getAnotherObjectNot(Person person) {
person = new Person();
person.setName("George");
}
En, terug in het main
, onder de aanroep van setAnotherName
, laten we deze methode en een andere println-aanroep aanroepen:
getAnotherObjectNot(person);
System.out.println(person.getName());
Nu zou het programma afdrukken:
Linda 5
Linda
Wat gebeurde er met het object dat George had? Nou, de parameter die werd doorgegeven was een wijzer naar Linda; Toen de methode getAnotherObjectNot
een nieuw object maakte, verving het de verwijzing naar het Linda-object door een verwijzing naar het George-object. De Linda object bestaat nog steeds (op de heap), de main
methode nog steeds toegang, maar de getAnotherObjectNot
methode niet zou kunnen doen met het na dat, omdat het geen verwijzing ernaar. Het lijkt erop dat de schrijver van de code bedoeld was voor de methode om een nieuw object te maken en terug te geven, maar als dat zo was, werkte het niet.
Als dat is wat de schrijver wilde doen, zou hij het nieuw gecreëerde object van de methode moeten retourneren, zoiets als dit:
private static Person getAnotherObject() {
Person person = new Person();
person.setName("Mary");
return person;
}
Noem het dan zo:
Person mary;
mary = getAnotherObject();
System.out.println(mary.getName());
En de volledige output van het programma zou nu zijn:
Linda 5
Linda
Mary
Hier is het hele programma, met beide toevoegingen:
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;
}
}