Instanzattribut per Getter Methode zuweisbar, warum?

Okury

Neues Mitglied
Guten Tag,

ich versuche auf ein Array per Getter Methode zuzugreifen, um darin Parameter zu speichern/ändern. Daraus ergibt sich ein Verständnisproblem.

  1. Es wurde eine Instanz (car1) von Car per Default Konstruktor erstellt. Darüber sind die Instanzmethoden & -attribute generell erreichbar (von sichtbarkeits Operatoren abgesehen), stimmt das?
  2. Instanzattribute sind per private Anweisung zu schützen. (Car.java Zeile 2 & 3)
  3. Die Zuweisung von car1.getHorsePower()=23; schlägt wie erwartet fehl, da es eine Getter Methode ist. Über car1.setHorsePower(23); funktioniert die Zuweisung wie erwartet.
  4. Über den Getter car1.getWheels()[1] = 2; kann ich der Instanzvariable den Wert 2 zuweisen. Das sollte über den Getter doch nicht möglich sein. Und hier liegt mein Verständnisproblem.
  5. Die Ausgabe zeigt 2 und 23. Das ist auch wie erwartet.
Da ich davon ausgehe das Java das tut was es tuen soll, muss mein Verständnis falsch sein. Kann hier jemand etwas Licht ins Dunkle bringen.

Hier noch der zugehörige Code.

Vielen Dank

[CODE lang="java" title="HelloWorld.class (Java Code)" highlight="5,6"]public class HelloWorld {
public static void main(String[] args) {
Car car1 = new Car();

car1.getHorsePower()=234; // zuweisen auf getHorsePower() nicht Möglich
car1.getWheels()[1] = 2; // zuweisen auf getWheels()[1] ist Möglich

car1.setHorsePower(23);
System.out.println(car1.getWheels()[1]);
int hp = car1.getHorsePower();
System.out.println(hp);
}
}[/CODE]

[CODE lang="java" title="Car.java (Java Klasse)" highlight=""]public class Car {
private int horsePower;
private int[] wheels = {0,1,2,3};

public int[] getWheels() {
return wheels;
}
public void setWheels(int[] wheels) {
this.wheels = wheels;
}
public int getHorsePower() {
return horsePower;
}
public void setHorsePower(int horsePower) {
this.horsePower = horsePower;
}
}[/CODE]
 

mihe7

Top Contributor
Dein Punkt 4 funktioniert, weil getWheels() ein Array zurückgibt. Du versuchst nun aber nicht, den Rückgabewert der Methode zu ändern, vielmehr greifst Du mit Hilfe des Index-Operators ([]) in das zurückgegebene Array hinein und änderst einen Wert.

Das ist, wie wenn Du mir Dein Portemonnaie gibst. Ich kann daraus kein anderes zaubern, aber ich kann sehr wohl den Inhalt ändern :)
 
Zuletzt bearbeitet:

temi

Top Contributor
Und vor allem verhält sich ein Array wie ein Objekt, d.h. die Arrayvariable enthält nicht das Array, sondern eine Referenz auf das Array (also grob gesagt, einen Verweis auf den Speicherort, an dem sich der tatsächliche Inhalt des Arrays befindet).

Dein Getter gibt eine Kopie dieser Referenz zurück, d. h. sowohl die private Arrayvariable, als auch die Rückgabe "zeigen" auf den selben Inhalt. Darum kannst du über diese Referenz auch den Inhalt der privaten Variable ändern.

Möchtest du das verhindern, dann musst du eine (Referenz auf eine) Kopie des Arrays zurück geben. Die kann man dann zwar auch ändern, aber das private Original bleibt so wie es ist.

Java:
// dieses hier:
car1.getWheels()[1] = 2; // zuweisen auf getWheels()[1] ist möglich

// entspricht diesem:

int[] wheels = car1.getWheels(); // gibt die Referenz auf das interne Array zurück
wheels[1] = 2; // ändert den Inhalt

Probier doch mal:
Java:
public int[] getWheels() {
    return wheels.clone();
}
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Also dazu noch einmal ein paar Sichten:

a) rein logisch: Die Methode kann ja einfach den Wert eines Literals zurück geben:
public int getNumber { return 42; }
Das sollte aufzeigen, dass eine Zuweisung keinen Sinn machen kann, denn wo sollte da der Wert hin geschrieben werden?

b) Java Spezifikation: Nach der Java Spezifikation gibt es keine Zeiger sondern nur Values und Referenzen. Referenzen sind dabei von der JVM verwaltete Adressen, an denen komplexe Typen (Instanzen oder Array) zu finden sind. Generell werden diese Werte immer nur kopiert, d.h. egal ob bei einer Zuweisung, einem Parameter oder einer Rückgabe: Genau dieser Wert wird KOPIERT. Bei Parametern hat dies einen expliziten Namen: Call by Value. Du kannst mit diesen Werten diverse Dinge machen: Diese in einer Variablen speichern, woanders hin übergeben oder direkt in einer Operation nutzen. Wie @mihe7 schon sagte: Die [] sind einer Operation auf der Array Referenz.

c) Aus der Clean Code Sicht: Es gibt Getter und Setter. Über den Getter einen Wert verändern wäre ein wenig dumm. Wenn ich sage: Gib mit 10€, dann ist die Erwartungshaltung, dass Du mir Geld gibst. Da ist die Erwartungshaltung nicht, dass Du mir alle Taschen leer machst. Das wäre dann halt nicht "Gib mir 10€" sondern ein "Raube mich aus". Also ein klares Unterschied und diesen Unterschied gibt es natürlich auch zwischen Getter und Setter.
 

davidchsg

Neues Mitglied
Und vor allem verhält sich ein Array wie ein Objekt, d.h. die Arrayvariable enthält nicht das Array, sondern eine Referenz auf das Array (also grob gesagt, einen Verweis auf den Speicherort, an dem sich der tatsächliche Inhalt des Arrays befindet).

Dein Getter gibt eine Kopie dieser Referenz zurück, d. h. sowohl die private Arrayvariable, als auch die Rückgabe "zeigen" auf den selben Inhalt. Darum kannst du über diese Referenz auch den Inhalt der privaten Variable ändern.

Möchtest du das verhindern, dann musst du eine (Referenz auf eine) Kopie des Arrays zurück geben. Die kann man dann zwar auch ändern, aber das private Original bleibt so wie es ist.

Java:
// dieses hier:
car1.getWheels()[1] = 2; // zuweisen auf getWheels()[1] ist möglich

// entspricht diesem:

int[] wheels = car1.getWheels(); // gibt die Referenz auf das interne Array zurück
wheels[1] = 2; // ändert den Inhalt

Probier doch mal:
Java:
public int[] getWheels() {
    return wheels.clone();
}
und
3. schlägt fehl, weil primitive Datentypen per se unveränderbar sind.
 

davidchsg

Neues Mitglied
Und vor allem verhält sich ein Array wie ein Objekt, d.h. die Arrayvariable enthält nicht das Array, sondern eine Referenz auf das Array (also grob gesagt, einen Verweis auf den Speicherort, an dem sich der tatsächliche Inhalt des Arrays befindet).

Dein Getter gibt eine Kopie dieser Referenz zurück, d. h. sowohl die private Arrayvariable, als auch die Rückgabe "zeigen" auf den selben Inhalt. Darum kannst du über diese Referenz auch den Inhalt der privaten Variable ändern.

Möchtest du das verhindern, dann musst du eine (Referenz auf eine) Kopie des Arrays zurück geben. Die kann man dann zwar auch ändern, aber das private Original bleibt so wie es ist.

Java:
// dieses hier:
car1.getWheels()[1] = 2; // zuweisen auf getWheels()[1] ist möglich

// entspricht diesem:

int[] wheels = car1.getWheels(); // gibt die Referenz auf das interne Array zurück
wheels[1] = 2; // ändert den Inhalt

Probier doch mal:
Java:
public int[] getWheels() {
    return wheels.clone();
[/QUOTE]
und:
3. schlägt fehl, weil primitive Datentypen per se unveränderbar sind.
 

Neumi5694

Top Contributor
Arrays sind im Normalfall eh keine gute Idee.
Ein Array kannst du nicht vor Schreibzugriff schützen.
@davidchsg hat bereits eine gute Möglichkeit genannt, wie du zumindest potentiell negative Auswirkungen verhindern kannst, du lieferst nicht das Array selbst, sondern eine Kopie davon.
Persönlich hätte ich zu System.arraycopy gegriffen, aber das Klonen macht wahrscheinlich auch nichts anderes, hab grad nicht die Muse, das zu prüfen.

Eine Alternative wäre der Verzicht auf Arrays und das Arbeiten mit Listen.
Hier hast du nämlich eine ziemlich geniale Methode verfügbar.

Java:
public List<Integer> getWheels() {
    return Collections.unmodifiableList(myListOfWheels);
}

Hier wird die Liste in einen Wrapper gepackt, der beim Versuch, darauf zu schreiben, eine Exception auslöst.
Ähnliche Methoden gibt's für Maps und Sets.


Wichtig: Das Array selbst enthält in diesem Fall nur integer-Werte, kein großes Ding. Aber wenn du z.B. Points lieferst, dann können die Werte dieser Points auch weiterhin geändert werden.

Code:
myObject.getPoint().setLocation(4,5)
ist sehr oft erwünscht, aber nicht immer (ich versuch so was nach Möglichkeit zu vermeiden, sowohl bei set als auch bei get werden im Normalfall Kopien angelegt, bzw. die Werte übertragen und nicht das Objekt direkt zugewiesen)


Du müsstest auch jedes einzelne Element dieses Arrays oder der Liste entweder schützen oder kopieren (Stichwort DeepCopy/ShallowCopy/FlatCopy).
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Unterschied Instanzattribut und Referenzvariable Java Basics - Anfänger-Themen 4
T Getter/Setter - wie sieht ein Setter aus? Und wie nicht? Java Basics - Anfänger-Themen 34
Say Class scope und Instance scope und Getter nur selbstgeschrieben Methoden Java Basics - Anfänger-Themen 11
W Getter/Setter Java Basics - Anfänger-Themen 4
W Unterschiede bei Zugriff auf Objekt und Klassenvariablen über einen Getter? Java Basics - Anfänger-Themen 2
KogoroMori21 Objektvariable anderer Klasse übernehmen, Getter/Setter Java Basics - Anfänger-Themen 11
T Verständnisfrage Objekt Getter Setter Java Basics - Anfänger-Themen 102
KogoroMori21 Getter und Setter Java Basics - Anfänger-Themen 5
P Klassenübergreifende Ausgabe mittels "getter" nicht möglich Java Basics - Anfänger-Themen 21
J Array über Getter erlangen Java Basics - Anfänger-Themen 34
S Klassen instanziieren und verwenden von Getter und Setter Java Basics - Anfänger-Themen 4
P Klasse hat keinen Zugriff auf getter/setter-Methoden eines Objektes Java Basics - Anfänger-Themen 9
V getter/setter Garage Java Basics - Anfänger-Themen 12
M Getter einer PriorityQueue Java Basics - Anfänger-Themen 1
KopaCoda Getter mehrfach aufrufen -> ist das guter code? Java Basics - Anfänger-Themen 3
V Getter Methode Java Basics - Anfänger-Themen 38
S getter, setter in abstrakter Klasse oder lieber Unterklassen Java Basics - Anfänger-Themen 4
topi Kapselung getter und setter Java Basics - Anfänger-Themen 5
D Setter/Getter für Instanzvariablen praktisch? Java Basics - Anfänger-Themen 19
S Getter/Setter - Variablenklasse ? Java Basics - Anfänger-Themen 5
S getter and setter Java Basics - Anfänger-Themen 12
L Getter und Setter Java Basics - Anfänger-Themen 2
T Extrahiertes Objekt durch Getter bekommen Java Basics - Anfänger-Themen 2
M Generics getter und setter Methoden Java Basics - Anfänger-Themen 4
D Kapselung final Variablen mit Getter? Java Basics - Anfänger-Themen 2
A getter Java Basics - Anfänger-Themen 3
E Methoden Objekte in Methode aufrufen ohne getter und setter? Java Basics - Anfänger-Themen 1
T Getter für Array Java Basics - Anfänger-Themen 4
J-Gallus Ein Getter bekommt eine anderen Type als er Return soll Java Basics - Anfänger-Themen 9
K Public Attribute oder getter - funktioniert leider beides hier nicht Java Basics - Anfänger-Themen 5
L Klassen - Getter & Setter Methoden Java Basics - Anfänger-Themen 2
D Erste Schritte Java - Setter und Getter Java Basics - Anfänger-Themen 1
Z Getter/Setter NullPointer Exception Java Basics - Anfänger-Themen 6
P getter Java Basics - Anfänger-Themen 1
K Klassen Setter/Getter Java Basics - Anfänger-Themen 3
F OOP Schleifen und Probleme mit Setter und Getter Java Basics - Anfänger-Themen 1
L Setter und Getter/Vererbung Java Basics - Anfänger-Themen 6
M Getter Problematik mit ItemListener Java Basics - Anfänger-Themen 17
K Kapselung getter & setter Java Basics - Anfänger-Themen 11
S Array und Getter-Methode Java Basics - Anfänger-Themen 2
Avarion Getter von Super-Klasse funktioniert nicht Java Basics - Anfänger-Themen 10
J Frage zu Setter u. Getter Java Basics - Anfänger-Themen 7
T Variablen Getter-Setter vs Public Variable? Java Basics - Anfänger-Themen 5
Y Konstruktor - Setter/Getter Java Basics - Anfänger-Themen 3
N Klassen fragen zur getter und setter methode Java Basics - Anfänger-Themen 11
D Ab wann getter und setter Java Basics - Anfänger-Themen 2
J Variable per Getter holen - wie ? Java Basics - Anfänger-Themen 2
K getter & setter Java Basics - Anfänger-Themen 6
C getter/setter Problem anscheinend Java Basics - Anfänger-Themen 13
D Getter Mehtode Unsicher Java Basics - Anfänger-Themen 6
G Erste Schritte Getter und Setter Java Basics - Anfänger-Themen 12
B Getter,Setter - Konstruktor überflüssig? Java Basics - Anfänger-Themen 26
N Sprite Methode (Getter, Setter, Konstruktor) Java Basics - Anfänger-Themen 9
S getter/setter aufrufen Java Basics - Anfänger-Themen 9
B Java getter/setter funktioniert nicht! Java Basics - Anfänger-Themen 7
X OOP Getter/Setter überschreiben den Wert ihrer Variablen nicht Java Basics - Anfänger-Themen 4
T Erste Schritte Verständnisfrage: Getter und Setter Methoden Java Basics - Anfänger-Themen 3
M Problem mit getter, liefert nur alte Werte Java Basics - Anfänger-Themen 6
V public Variablen vs Getter + Setter Java Basics - Anfänger-Themen 4
F Getter und Setter Java Basics - Anfänger-Themen 4
lulas[]args getter/setter umstellung Java Basics - Anfänger-Themen 6
El_Lobo Methoden Zu viele Getter- und Settermethoden - geht das einfacher? Java Basics - Anfänger-Themen 3
G Generics kein Zugriff auf getter eines Objekts Java Basics - Anfänger-Themen 4
B Klassen Getter-Setter vor neuem Klassenaufruf - wie? Java Basics - Anfänger-Themen 20
M OOP Aufruf vieler Getter Methoden abkürzen? Java Basics - Anfänger-Themen 7
N OOP Getter, Setter und andere Probleme Java Basics - Anfänger-Themen 8
A OOP Getter und Setter Java Basics - Anfänger-Themen 18
MU5T4NG Getter und Setten bei GUI-Erstellung Java Basics - Anfänger-Themen 13
B Variablen keine Arrayübergabe für getter im Interface Java Basics - Anfänger-Themen 8
L Unterschied Konstruktor / Getter Setter Java Basics - Anfänger-Themen 13
L Setter und Getter für Arrays? Java Basics - Anfänger-Themen 4
N boolean bei Setter und getter methoden Java Basics - Anfänger-Themen 21
J int Wert mit getter holen und in String parsen Java Basics - Anfänger-Themen 5
O Universeller GETTER Java Basics - Anfänger-Themen 5
J Die Getter Methode Java Basics - Anfänger-Themen 6
J Getter und Setter auch intern benutzen - guter Stil? Java Basics - Anfänger-Themen 31
Houly Setter/Getter MEthoden testen Java Basics - Anfänger-Themen 4
P OOP Getter&Setter Methoden funktionieren nicht Java Basics - Anfänger-Themen 7
E [Erledigt] Schöner Code zur Reduktion von unzähligen Getter-Methoden Java Basics - Anfänger-Themen 2
H Setter-und-Getter-Konvention Java Basics - Anfänger-Themen 8
V Reflection API - getter und setter Java Basics - Anfänger-Themen 7
-horn- EINE setter/getter klasse aus mehreren klassen befüllen Java Basics - Anfänger-Themen 13
C Getter/Setter Java Basics - Anfänger-Themen 61
F 2 dimensionales Array getter Methode Java Basics - Anfänger-Themen 3
H Frage zu getter und setter Java Basics - Anfänger-Themen 5
S Unbenutzte/überflüssige Getter/Setter herausfinden? Java Basics - Anfänger-Themen 2
K Getter Java Basics - Anfänger-Themen 6
M getter/setter bei JTextField ? Java Basics - Anfänger-Themen 21
G warum Setter/Getter Java Basics - Anfänger-Themen 25
S In einer Liste auf getter und setter zugreifen Java Basics - Anfänger-Themen 6
S JTextField in anderer Classe mit getter Methode auslesen. Java Basics - Anfänger-Themen 2
M if oder verschiedene getter Java Basics - Anfänger-Themen 31
T Rekursive Methode Java Basics - Anfänger-Themen 13
Ü Methode soll Quadrat aus der Summer zurückgeben Java Basics - Anfänger-Themen 10
P Objekt einer Methode eines anderen Objektes übergeben Java Basics - Anfänger-Themen 5
Leyla Spezifischte Methode Java Basics - Anfänger-Themen 16
M Methode zielnah zeigt das gewünschte Ausgabe nicht an Java Basics - Anfänger-Themen 3
L Variablenwerte aus einer Methode übergeben Java Basics - Anfänger-Themen 2
T Methode soll etwas ausrechnen und zurückgeben (klappt nd) hat wer eine Idee? Java Basics - Anfänger-Themen 11
P Main Methode scheint Constructor aufzurufen, ohne dass es so gecoded ist Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben