Referenzen auf Objekte

JavaJoe?

Grünschnabel
Hallöchen an alle,
das ist sicher eine gute Anfänger frage die sicher schon sehr oft gestellt wurde!
Wie schaft man also das "Anfängerparadoxon" zu lösen?

lg Joe?

HTML:
1: import java.awt.Point;
 2:
 3: class ReferencesTest {
 4:     public static void main (String arguments[]) {
 5:         Point pt1, pt2;
 6:         pt1 = new Point(100, 100);
 7:         pt2 = pt1;
 8:
 9:         pt1.x = 200;
10:         pt1.y = 200;
11:         System.out.println("Point1: " + pt1.x + ", " + pt1.y);
12:         System.out.println("Point2: " + pt2.x + ", " + pt2.y);
13:     }
14: }
 
In dem Fall übernimmt pt2 die selbe Referenz wie pt1. Damit pt2 nur die Werte übernimmt und nicht auch die Referenz, kannst du z.B. die Methode clone() von pt1 verwenden.

Damit ein Objekt geclont werden kann, muss es das Interface Cloneable implementieren. Die meisten Klassen tun dies bereits, bei selbstgeschriebenen Klassen muss man das Interface halt implementieren.
 
Also, kann man das nicht einfach manchen, auser das man sich ein Interface schreiben muss?

habe grade noch gelesen:

HTML:
...
str1 = "Free the bound periodicals.";
str2 = str1;
...
11:         str2 = new String(str1);

Sollte das auch so gehen, wenn man sich ein Konstruktor schreibt?

lg Joe?
 
Also, kann man das nicht einfach manchen, auser das man sich ein Interface schreiben muss?
Du brauchst kein Interface zu schreiben, Coneable ist Bestandteil von Java, sowie viele weitere Interfaces auch. Cloneable brauchst du nur für die Methode clone(). Es gibt natürlich auch andere Wege, z.B. über den Konstruktor.

Entscheidend ist halt, wie du die Objekte kopieren willst. Ich persönlich greife zur Methode clone().

Ich hab hier mal nen Beispiel gemacht, das sowohl die Methode clone() als auch einen Konstruktor zum Kopieren benutzt.

Java:
package testlauf.objekte.referenzen;

public class ReferenzTest {
	public static void main(String[] args) {
		TestPoint o1 = null;
		TestPoint o2 = null;
		TestPoint o3 = null;

		// Erstes Objekt erzeugen und Werte setzen.
		o1 = new TestPoint();
		o1.x = 10;
		o1.y = 20;

		// Zweites Objekt durch Clonen des ersten Objektes erzeugen.
		try {
			o2 = (TestPoint)o1.clone();
		} catch(CloneNotSupportedException e) {
			e.printStackTrace();
		}

		// Werte des ersten Objektes ändern.
		o1.x = 125;
		o1.y = 250;

		// Drittes Objekt erzeugen und die Werte des an den Konstruktor
		// übergebenen Objektes übernehmen.
		o3 = new TestPoint(o1);

		// Nochmal die Werte des ersten Objektes ändern.
		o1.x = 1024;
		o1.y = 2048;

		// Alles ausgeben.
		System.out.println("Point1: " + o1.x + ", " + o1.y);
		System.out.println("Point2: " + o2.x + ", " + o2.y);
		System.out.println("Point3: " + o3.x + ", " + o3.y);
	}
}

class TestPoint implements Cloneable {
	public int x = 0;
	public int y = 0;

	/**
	 * Default-Konstruktor.
	 */
	public TestPoint() {
	}

	/**
	 * Kopier-Konstruktor.
	 * 
	 * @param p
	 *            Objekt, dessen Werte übernommen werden sollen.
	 */
	public TestPoint(TestPoint p) {
		this();
		x = p.x;
		y = p.y;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
}
Ausgabe:
Point1: 1024, 2048
Point2: 10, 20
Point3: 125, 250

Damit nicht die Referenz übernommen wird, sondern nur die Werte, muss man ein neues Objekt erzeugen und dieses dann mit den Werten des "Originals" füttern. Dann hat das neue Objekt natürlich eine andere Referenz, was Objekt1 != Objekt2 ausmacht, obwohl sie die gleichen Werte haben. Da es sich dabei um verschiedene Referenzen handelt, kann man bei einem Objekt die Werte ohne Probleme ändern, ohne dass es Auswirkungen auf die anderen Objekte hat.
 
Zuletzt bearbeitet:
Wenn das mit clone nicht funktioniert müsstest du die Attribute selbst auf ein neues Objekt setzen (oder um genau zu sein eine neue Instanz).

Java:
pt1 = new Point(100, 100);
pt2 = new Point(pt1.getX(),pt1.getY());
 
Ja wie gesagt, es kommt drauf an, wie man das machen will. Viele Klassen bieten schon recht gute Möglichkeiten, bei selbstgeschriebenen muss man die Sachen selbst implementieren. Zur Not benutzt man die Getter und Setter.
 
Clone ist eklig IMHO, wegen der checked Exception, die der Client fangen muss. Wenn man kopierende Funktionalität braucht ist man IMHO besser bedient einen Konstruktor oder eine Factorymethode anzubieten, die eben den gleichen Typ als Parameter aufnimmt. Point bietet ja bereits einen solchen Konstruktor.

Gruß
Ollie
 
clone() ist für solche kleinen (flachen) Klassen in Ordnung. Man hat da nicht das Problem, eine tiefe Kopie erzeugen zu müssen.
Man kann die clone()-Methode überschreiben und dabei die Exception schlucken, dann hat man keine Probleme mit dem Handling. Das sie eine checked Exception ist, ist natürlich dämlich.
 

Neue Beiträge

Zurück