neues Objekt speichern, nicht Referenz

Miriam90

Mitglied
Hallo,

ich habe ein Objekt Snake und dieses wiederum einthält neben anderen Eigenschaften eine Liste aus Segmenten. In der Klasse Segment gibt es x und y als Koordinaten.

Ich dachte jetzt, es wäre ganz einfach, mir einen Zustand meiner Snake zu merken. Ich wollte also sowas wie

Java:
Snake oldSnake = snake

machen. Aber anscheinend speichere ich mir damit nur die Referenz, sodass ich oldSnake immer das gleiche drinsteht wie in snake. Hat das irgendwas mit mutable und immutable zutun? Wie bekommt man es hin, dass man wirklich die Daten speichert und nicht nur eine Referenz?

Mit dem Thema hatte ich schonmal ein riesiges Problem und bin es dann irgendwie kompliziert umgangen. Da ich nun schon wieder darauf stoße, frage ich die Experten und hoffe, dass ich etwas dazu lernen kann.

Grüße,

Miriam
 
N

nillehammer

Gast
Aber anscheinend speichere ich mir damit nur die Referenz, sodass ich oldSnake immer das gleiche drinsteht wie in snake.
Ja, in Java arbeitest Du grundsätzlich mit Referenzen. Wenn du eine neue Instanz von irgendwas erzeugen willst, musst Du das explizit programmieren.
Hat das irgendwas mit mutable und immutable zutun?
Nein, mutable/immutable ist eine Eigenschaft von Instanzen, die der Programmierer gewählt hat. Es sagt aus, ob Werte, die in einer Instanz gespeichert sind, geändert werden können oder nicht. Dazu folgende Codebeispiele:
Java:
// Gutes immutable, alle Inszanzvariablen sind final und es gibt keinen Code, der sie ändert.
public class GoodImmutable {

  private final String name;

  public GoodImmutable(final String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }
}
// Nicht so gutes immutable. Die Instanzvariable ist nicht final.
// Aber, weil es keinen Code gibt, der sie ändert und man wg. private
// auch von draußen nicht rankommt, ist es trotzdem immutable
public class NotSoGoodImmutable {

  private String name;

  public NotSoGoodImmutable(final String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }
}

// Mutable, die Instanzvariable kann verändert werden.
public class Mutable {

  private String name;

  public Mutable(final String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }

  public void setName(final String name) {
    this.name = name;
  }
}
Wie bekommt man es hin, dass man wirklich die Daten speichert und nicht nur eine Referenz?
Wie gesagt, Du musst explizit eine neue Instanz als Kopie erzeugen. Nur dann sind die Inszanzen wirklich unabhängig und es kommt nicht zu unerwünschtem Sharing. Dazu gibt es verschiedene Möglichkeiten:
- Implementiere Cloneable
- Schreibe einen Copy-Construktor
- Erzeuge eine neue Inszanz und ruf danach alle setter auf, um die Daten in der neuen Instanz zu haben
 

Miriam90

Mitglied
Wow, danke für die schnellen Antworten! Das hört sich sehr einleuchtend an =) An der praktischen Umsetzung haperts noch ein wenig..

Java:
public class Snake implements Cloneable{
	private List <Segment> segments = new ArrayList <Segment>();	
	private Character direction;								
	private int newx;	
	// ...

	protected Object clone() throws CloneNotSupportedException {
		Snake clone=(Snake)super.clone(); 
		clone.segments = segments;
		clone.direction = direction;
		clone.newx = newx;
		//...
		return clone;
	}
}

Java:
public class Segment implements Cloneable {
	private String typ;					
	private Color colour;					
	private int x;							
	private int y;
	
	 protected Object clone() throws CloneNotSupportedException {
		    Segment clone=(Segment)super.clone(); 	
		    clone.typ = typ;
		    clone.colour = colour;
		    clone.x = x;
		    clone.y = y;	    
		    return clone;
	 }
}

Damit scheine ich noch nicht fertig zu sein. Was fehlt noch?
 
G

Gast2

Gast
Java:
clone.segments = segments;
Damit teilen sich beide Schlangen wieder die selbe Liste. Du musst jedes Objekt (dass nicht immutable ist) klonen dass du in deiner Snake Klasse hast.
 
N

nillehammer

Gast
Wie und wo mache ich das? Kannst du dazu ein Codebeispiel zeigen?
Du erzeugst ja schon beim Construieren jeweils eine neue ArrayList. Dieser kannst Du einfach alle Elemente hinzufügen
Java:
    public Object clone() throws CloneNotSupportedException {
        Snake clone=(Snake)super.clone();
        clone.segments.addAll(this.segments);
        //...
        clone.direction = direction;
        clone.newx = newx;
        //...
        return clone;
    }

Wenn Du jedes Segment selbst noch clonen willst, iterier händisch über die Liste von Segments und füge sie einzeln in die neue Liste ein.
 
Zuletzt bearbeitet von einem Moderator:

Miriam90

Mitglied
Java:
	        final List<Segment> clonedSegments = new ArrayList<Segment>(this.segments.size());
	        for (Segment s : segments){
	        	clonedSegments.add(s);
	        }
	        clone.segments = clonedSegments;

Also so?
Sorry, dass ich so schwer von Begriff bin - aber müsste ich dann nicht durch diese Änderung fertig sein? Oder gibts noch andere Stellen?
 
N

nillehammer

Gast
Leider nein. Die Erzeugung der ArrayList ist unnötig. Aufgrund folgender Zeile im Snake-Code hast Du bei einer frisch erzeugten Snake bereits eine frische Liste:
Java:
    private List <Segment> segments = new ArrayList <Segment>();
Eine der beiden Listenerzeugungen kannst Du Dir also sparen.

Wenn du "nur" alle Segments der Liste hinzufügen wolltest (das machst Du in der Schleife), würde auch das reichen:
Java:
clone.segments.addAll(this.segments);
Jetzt hast Du das Listensharing beseitigt. Die einzelnen Elemente in der Liste (die Segmente) werden aber immer noch geshared. Ist das schlimm? Nein, wenn Segment immutable ist. Dann bist Du fertig. Wenn Segment mutable ist (dazu siehe mein vorletzter Post), musst Du auch hier für unabhängige Instanzen sorgen . Bau dafür den clone-Befehl noch in Deine Schleife ein:
Java:
Segment clonedSegment = (Segment) s.clone();
 

Miriam90

Mitglied
Jaaaa =)))
Ganz ganz großen Dank an euch alle!! Wenn ich jetzt nicht was fürs Leben gelernt hab =D Da macht das Studium doch endlich mal richtig Sinn^^
Danke auch für alle Begriffserläuterungen - werden nicht ignoriert, falls ihr das befürchtet habt ;) Hatte ja zum Großteil auch ein Problem bei der Lösung, weil ich nicht genau wusste, nach was ich suche bzw. wie ich das betiteln soll.

Miriam
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Neues Objekt darstellen Allgemeine Java-Themen 4
G Neues Objekt aus List<JsonObject> mit Stream Allgemeine Java-Themen 4
F Neues Objekt aus .CSV definition Allgemeine Java-Themen 3
V Neues Objekt anlegen, welcher Typ? Allgemeine Java-Themen 2
T HashMap#get neues Objekt, selber Inhalt Allgemeine Java-Themen 12
T Per Reflection neues Objekt erzeugen Allgemeine Java-Themen 3
I "Neues" Lizenzmodell Oracle - JRE nicht mehr zur Redistribution freigegeben? Allgemeine Java-Themen 16
Ullenboom Ein neues Java-Buch entsteht, willst du helfen? Allgemeine Java-Themen 7
coolian Swing erstellt fillreckt immmer ein neues object Allgemeine Java-Themen 13
D Mit Hilfe von Java aus Excel-Sheet Zellen in neues Excel Dokument kopieren Allgemeine Java-Themen 3
J Erkennen, ob Programm in JAR (neues Problem) Allgemeine Java-Themen 7
A String Array Werte in neues String Array übernehmen Allgemeine Java-Themen 5
127.0.0.1 Subversion neues SVN Projekt, keine Main gefunden ?! Allgemeine Java-Themen 7
X Neues Spiel/ Neustart Allgemeine Java-Themen 5
A irgendwas neues für MP3 ? Allgemeine Java-Themen 2
F Log Appender für neues Logfile Allgemeine Java-Themen 3
E Neues Projekt - Welche GUI / IDE /Techniken / etc. Allgemeine Java-Themen 14
J TreeSet neues TreeSet aufbauen Allgemeine Java-Themen 8
L Methode "Neues Spiel" für Memory Allgemeine Java-Themen 2
L Java6 update N bekommt neues Browser-Plugin, bitte testen. Allgemeine Java-Themen 7
M Neues JPanel in JFrame einbinden Allgemeine Java-Themen 6
F neues fenster Allgemeine Java-Themen 3
M -->: Seite war mit Virus infiziert, daher neues Thema . Allgemeine Java-Themen 3
S In der For-schleife jeweils ein neues Array erstellen Allgemeine Java-Themen 8
K Cast ohne neues Object zu erzeugen Allgemeine Java-Themen 12
G eigene klassen die ein jar verwenden als neues jar erstellen Allgemeine Java-Themen 4
L-ectron-X Neues in J2SE 1.5 Allgemeine Java-Themen 6
N Lwjgl 3d Objekt wird schmaler, wenn es sich dreht Allgemeine Java-Themen 0
B Ein Objekt einer Klasse mehreren anderen Klassen zur Verfügung stellen? Allgemeine Java-Themen 6
T Objekt Array Aufgabe mit Busdatenbank Allgemeine Java-Themen 2
Maxi-JOO Klassen Dummy Objekt in anderen Constructor übergeben Allgemeine Java-Themen 5
el_niiinho13 Objekt auf der Konsole ausgeben lassen Allgemeine Java-Themen 8
d.lumpi Aus Einer Klasse auf ein Objekt einer anderen Klasse Zugreifen Allgemeine Java-Themen 1
A Objekt aus anderen Objekten machen Allgemeine Java-Themen 8
SaftigMelo In einem Winkel Objekt bewegen Allgemeine Java-Themen 2
E Datentypen Wie kann ich die Längen der unterschiedlichen Ebenen aus einem Objekt lesen von dem ich weiß, dass es ein mehrdimensionaler Array ist? Allgemeine Java-Themen 3
H Objekt speichern und laden Allgemeine Java-Themen 1
H Objekt speichern und laden Allgemeine Java-Themen 1
J Objekt in Bytestream umwandeln Allgemeine Java-Themen 12
J Wie kann ich von Vornherrein einen Fokus auf ein Objekt entfernen? Allgemeine Java-Themen 3
J Information von getSource() Objekt auslesen Allgemeine Java-Themen 1
Drachenbauer Wie stelle ich fest, ob ein Objekt in meinem Array vorkommt? Allgemeine Java-Themen 5
S Variable als Objekt Name Allgemeine Java-Themen 3
D Input/Output Zwischen zwei ID-Räumen unterscheiden und Objekt löschen Allgemeine Java-Themen 16
L Objekt aus Objekt-array "löschen" Allgemeine Java-Themen 2
T Objekt mit String und Int aus TxT Datei erstellen Allgemeine Java-Themen 23
T Objekt in Array packen Allgemeine Java-Themen 6
K Methodenaufruf mit String / String zu Objekt konvertieren Allgemeine Java-Themen 8
J Best Practice Objekt an alle Klassen verteilen ( Discord Bot ) Allgemeine Java-Themen 7
D Objekt-Suche mit mehreren optionalen Parametern Allgemeine Java-Themen 6
M Klassen Objekt weiter geben Allgemeine Java-Themen 1
B Klassen Objekt erzeugen und Konstruktor aufrufen - Welche Lösung ist besser? Allgemeine Java-Themen 2
L Variablen Eigenes Objekt wie z.B. einen Integer zuweisen Allgemeine Java-Themen 3
D Konstruktor - jedes Objekt einzeln erzeugen - alternative? Allgemeine Java-Themen 8
S Applet Überprüfen ob ein Objekt angeklickt wurde Allgemeine Java-Themen 2
RalleYTN 3D Objekt Translation basierend auf Rotation (Probleme mit Z Rotation) Allgemeine Java-Themen 0
B Von String zu <Objekt> ||Speichern/Laden Allgemeine Java-Themen 17
P Threads Objekt im Konstruktor anders wie im Run()-Block Allgemeine Java-Themen 10
R Objekt funktioniert nicht auf iOS Allgemeine Java-Themen 15
K Textdatei als Objekt Allgemeine Java-Themen 4
Viktim Classenname zu Objekt Allgemeine Java-Themen 4
P Entity Objekt Methoden vs Service methoden Allgemeine Java-Themen 2
D Datentypen Klassenattribut aus Objekt in generischer Liste Allgemeine Java-Themen 15
O Klassen Bruch im gleichen Objekt Speichern Allgemeine Java-Themen 1
P Liste zu Objekt umwandeln Allgemeine Java-Themen 4
C Liste checken auf MINDESTENS ein Objekt | Bukkit Allgemeine Java-Themen 3
K Best Practice JFrame Objekt allgemein zugänglich machen Allgemeine Java-Themen 8
B ArrayList in ein Objekt legen Allgemeine Java-Themen 1
D Objekt entlang eines Funktionsgraphens bewegen Allgemeine Java-Themen 6
M Objekt serialisieren/deserialisieren und in einer SQLite-Datenbank speichern Allgemeine Java-Themen 3
D Java Objekt als Service in Runtime registrieren Allgemeine Java-Themen 1
S Interaktion mit einer website (website als Objekt?) Allgemeine Java-Themen 3
J OOP Überwachen, ob ein Objekt erzeugt wird Allgemeine Java-Themen 9
S Byte Array welches in Laufzeit aufgelöst wird // Objekt Array Allgemeine Java-Themen 3
Thallius Hash über serialisiertes Objekt? Allgemeine Java-Themen 3
Developer_X Input/Output Serialisiertes Objekt speichern und laden Allgemeine Java-Themen 1
C Generics Objekt in ArrayList Allgemeine Java-Themen 2
L Klassen Konstruktor soll Objekt anderer Klasse erzeugen Allgemeine Java-Themen 2
K Methoden Objekt wird nicht erkannt Allgemeine Java-Themen 11
P Objekt mit verschiedenen Datentypen Allgemeine Java-Themen 5
T Objekt kontaktiert seinen "erzeuger" Allgemeine Java-Themen 5
S Objekt orientierte Programmierung Allgemeine Java-Themen 7
C Objekt Datenverlust nach Methodenaufruf Allgemeine Java-Themen 9
H JavaFX Von einer Methode auf stage-Objekt zugreifen Allgemeine Java-Themen 3
T WeakReference/PhantomReference: Mitbekommen WELCHES Objekt nun GC'ed wird Allgemeine Java-Themen 2
T Class-Objekt mit URLClassloader Allgemeine Java-Themen 7
P Konsoleneingabe übernehmen und Objekt instanzieren. Allgemeine Java-Themen 5
E Auf Java-Objekt aus anderer Instanz zugreifen Allgemeine Java-Themen 26
L Klassen Polymorphie:2 Attribute gleichen Namens in einem Objekt Allgemeine Java-Themen 6
P Objekt Array in Datei Speichern Allgemeine Java-Themen 3
F Dynamisch ein Objekt einer bestimmten Subklasse erstellen Allgemeine Java-Themen 7
D Player Objekt - Frame über Server anzeigen lassen. Allgemeine Java-Themen 3
V Objekt löschen Allgemeine Java-Themen 7
A OOP Wie auf Objekt der Superklasse zugreifen? Allgemeine Java-Themen 6
S Datei in File-Objekt mit UTF-8 einlesen Allgemeine Java-Themen 2
B synchronisierter zugriff auf Objekt Allgemeine Java-Themen 6
F Objekt einer Datei verschieben, aber Verzeichnispfad fehlt Allgemeine Java-Themen 6
C Objekt Typ herausfinden Allgemeine Java-Themen 5
E Objekt beim Erzeugen in ArrayList Allgemeine Java-Themen 9
M Objekt prüfen auf null ->Invocation Target Exception??? Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben