Portal > Foren > Java > Allgemeine Java-Programmierung > Clone Methode treibt mich zum Wahnsinn
Antwort
 
Themen-Optionen Thema durchsuchen
Alt 22.01.2005, 22:34 Nach oben    #1
pro_evo
Gast
 
Beiträge: n/a
Standard Clone Methode treibt mich zum Wahnsinn

Hi all,

in unserem Script heißt es :

Zitat:
Der Feldname wird häufig auch als Referenz auf das Feld
bezeichnet.

Wenn statt der Kopie des Feldnamens (=„Hausnummer“) eine Kopie
des Inhalts (=„Haus“) gewünscht wird, so müssen die Werte aller
Komponenten kopiert werden.

Dies ist das sog. Clonen des Feldes.

Hierfür gibt es in Java eine clone-Anweisung.

Diese Kopie der Inhalte eines Feldes erfordert einen Aufwand, der
proportional zur Größe des Feldes ist.
sooooo für String[] Felder funzt das ganze auch 1a ... aaaaaaaaaaaaaaber hier nicht :

habe Keine Ahnung warum, denn die Klasse String überschreibt die clone() Methode von der Klasse Object NICHT (s. API).

Anbei der Code viel spaß beim testen :

Java Code:
  1. class Person  extends Object  {
  2.   String name;
  3.   public Person (String name) {
  4.     this.name = name;
  5.   }
  6.   public String toString  () {
  7.     return "Mein Name ist " + name;
  8.   }
  9.  
  10. }
  11.  
  12. public class Personen {
  13.   public static void main (String[] args) {
  14.  
  15.     Person[] personal = {new Person("Gamer"), new Person("Rul0r")};
  16.    
  17.     Object Temp     = personal.clone();
  18.     Person[] perso  = ((Person[])Temp);
  19.     perso[0].name   = "Noob";
  20.    
  21.     Person[] perso2 = (Person[])personal.clone();
  22.     perso2[1].name   = "Lamer";
  23.  
  24.     System.out.println (personal[0]);
  25.     System.out.println (personal[1]);
  26.    
  27.     // protected Fehler kommt bei Objekt (z.B. Person) clonen :
  28.     //Person p = new Person("Bauer");
  29.     //Person c = (Person)p.clone();
  30.      
  31.   } 
  32. }
  33.  
  34. /*Für String Felder geht clonen !!
  35. *
  36. *Methods inherited from class java.lang.Object
  37. *clone
  38. *
  39. *=> selbe Methode ! wurde nicht nicht überschrieben !*/

schonmal danke für Antworten
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 22.01.2005, 23:31 Nach oben    #2
Fuzzy
Gast
 
Beiträge: n/a
Standard

Hi,

bei clone gibt es zwei Dinge zu beachten:

1.) clone ist per default als protected definiert. Nur für bestimmte Klassen (und die Arrays gehören dazu) ist clone public. Um das zu ändern, muß eine public clone Methode in der Klasse angelegt werden.

2.) MUSS Cloneable implementiert werden. Dies ist ein Interface ohne Methode, d.h. es müssen gar keine Methoden überschrieben werden, aber wenn es nicht implementiert wird, funktioniert clone nicht.

Java Code:
  1. class Person implements Cloneable  {
  2.       String name;
  3.       public Person (String name) {
  4.         this.name = name;
  5.       }
  6.       public String toString  () {
  7.         return "Mein Name ist " + name;
  8.       }
  9.       
  10.         public Object clone() throws CloneNotSupportedException {
  11.             return super.clone();
  12.         }
  13.     }

Damit gehts.
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 22.01.2005, 23:55 Nach oben    #3
pro_evo
Gast
 
Beiträge: n/a
Standard

Vielen Dank das clonen von normalen Objekten funzt nun schonmal.

Jedoch habe ich immer noch das Problem bei dem oben geposteten Array.

Obwohl das Feld geklont ist , und ich im geklonten Feld die Namen ändere werden die auch in den Klon Quellen geändert, was ja nicht so ein soll.
(ist aber so, siehe Ausgabe)
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 23.01.2005, 00:09 Nach oben    #4
Fuzzy
Gast
 
Beiträge: n/a
Standard

Alles klar:

Du hast zwar das Feld geklont, aber clone funktioniert nur als "shallow" clone. Das bedeutet, dass nur die Referenzen kopiert werden, nicht aber die Objekte geklont werden.

Das gleiche gilt auch für den clone des Objektes. Auch hier wird nur die Referenz geklont. Das fällt aber nicht weiter auf, weil ein String ohnehin nicht verändert werden kann.

Wenn Du in einem Objekt aber auf andere veränderbare Objekte verweist, würde Dir das gleiche passieren.


P.S.
Ach ja, und was man auch nicht vergessen darf:
Java Code:
  1. public class XY implements Cloneable {
  2.    private final Map m = new HashMap();
  3.     ...
  4. }
führt dazu, dass nach dem Clonen die Variable m im "alten" und im geklonten Objekt auf dasselbe Objekt zeigen, ganz anders als man es erwarten sollte.
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 23.01.2005, 00:14 Nach oben    #5
Fuzzy
Gast
 
Beiträge: n/a
Standard

Euer Skript oben kann ich auf zwei Arten interpretieren :badgrin: :

A) Um ein Feld zu kopieren, müssen die einzelnen Objekte geklont werden, d.h. neues Feld und die einzelnen Objekte per clone kopieren.

oder

B) Der Autor des Skriptes hat keine Ahnung und glaubt irrtümlich, dass clone ein "deep copy" durchführt, bei dem auch die Inhalte kopiert werden bzw. hat sich mit dem Unterschied zwischen einem "shallow clone" und "deep clone" nicht so richtig vertraut gemacht.

Suchs Dir aus
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 23.01.2005, 00:43 Nach oben    #6
Fuzzy
Gast
 
Beiträge: n/a
Standard

Nachbemerkung:

Vermutlich ist es für die Lösung der Aufgabe nicht hilfreich, aber es gibt eine einfache Möglichkeit, ein deepClone mit Java-Bordmitteln zu erreichen. Hierfür müssen aber alle Element "Serializable" sein, die kopiert werden müssen.

Ich habe das Beispiel oben mal so umgestellt, dass ein deepCopy durchgeführt wird. Viel Spaß!

Java Code:
  1. class Person implements java.io.Serializable  {
  2.       String name;
  3.       public Person (String name) {
  4.         this.name = name;
  5.       }
  6.       public String toString  () {
  7.         return "Mein Name ist " + name;
  8.       }
  9.     }
  10.    
  11.     public class Personen {
  12.         public static Object deepClone(Object source) {
  13.             try {
  14.                 java.io.ByteArrayOutputStream outStream = new java.io.ByteArrayOutputStream();
  15.                 java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(outStream);
  16.                 oos.writeObject(source);
  17.                 java.io.InputStream inStream = new java.io.ByteArrayInputStream(outStream.toByteArray());
  18.                 java.io.ObjectInputStream ois = new java.io.ObjectInputStream(inStream);
  19.                 Object result = ois.readObject();
  20.                 oos.close();
  21.                 ois.close();
  22.                 return result;
  23.             } catch (java.io.IOException e) {
  24.                 throw new RuntimeException("Unexpected IOException", e);
  25.             } catch (ClassNotFoundException e) {
  26.                 throw new RuntimeException("Unexpected ClassNotFoundException", e);
  27.             }
  28.         }
  29.        
  30.         public static void main (String[] args) throws Exception {
  31.  
  32.         Person[] personal = {new Person("Gamer"), new Person("Rul0r")};
  33.       
  34.         Object Temp    = deepClone(personal);
  35.         Person[] perso  = ((Person[])Temp);
  36.         perso[0].name    = "Noob";
  37.       
  38.           Person[] perso2 = (Person[])deepClone(personal);
  39.           perso2[1].name   = "Lamer";
  40.  
  41.         System.out.println (personal[0]);
  42.         System.out.println (personal[1]);
  43.       
  44.         // protected Fehler kommt bei Objekt (z.B. Person) clonen :
  45.         Person p = new Person("Bauer");
  46.         Person c = (Person)deepClone(p);
  47.         
  48.       }
  49.     }
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 23.01.2005, 04:10 Nach oben    #7
pro_evo
Gast
 
Beiträge: n/a
Standard

waow vielen Dank für die Antwort !

Also ich glaub Ahnnug hat der Mann schon nur er kanns nicht in verständliches Deutsch bringen ... die deepClone Methode sieht sehr kompliziert aus, ich glaub sowas kann bei der Klausur nächste Woche ned verlangt werden *g*

ok also clone() macht eine flache Kopie ... schade aber warum scheint clone() bei String oder int Feldern tief zu sein ?
Wenn ich bei einem solchen geklonten Feld nämlich einen Wert ändere hat das keine Auswirkung auf die Quelle.
EDIT: Ahh ok bei den Basisdatentypen reicht die flache Kopie (Kopie der Werte, weil es keine Objekte sind), aber was ist mit String ?
Edit2: ahh ok das meinst du dann wohl hiermit:
Zitat:
Auch hier wird nur die Referenz geklont. Das fällt aber nicht weiter auf, weil ein String ohnehin nicht verändert werden kann.
sehr tricky das alles ...

Also folgendeswäre nun auch flach oder ? :
Java Code:
  1. int feld2[] = new int(feld1.length);
  2. for (int i=0; i<feld1.length; i++)
  3.     feld2[i] = feld1[i];

Juhu das hat mal wieder alles umgeworfen, aber wenisgtens weiß ich jez wies wirklich ist *g

Ich dachte nämlich das wäre eine flache Kopie:
int feld2[] = feld1;
Aber das is nun wohl eine Oberflache Kopie bzw. gar keine *juuhuu*

edit3: kurz zu der clone() Methode oben beim Personen Feld: Da wird für das neue PersonenFeld neuer Speicher angelegt , aber es kommen dieselben Objekte (Personen) rein ... stimmt das ?

danke nochmal

gruß
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 23.01.2005, 08:34 Nach oben    #8
Fuzzy
Gast
 
Beiträge: n/a
Standard

Spitze! Besser hätte ich es nicht erläutern können.

Zitat:
Zitat von pro_evo
kurz zu der clone() Methode oben beim Personen Feld: Da wird für das neue PersonenFeld neuer Speicher angelegt , aber es kommen dieselben Objekte (Personen) rein ... stimmt das ?
Exakt!

Vielleicht meint ja euer Dozent, dass int[] neu = alt eine flache Kopie ist, weil wirklich nur die Referenz kopiert wird und kein Objekt. Frag lieber nochmal nach bei der Begriffsdefinition. Bei solchen Definitionen haben Dozenten ja bekanntermaßen immer recht
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
PingBacks sind an
RefBacks sind aus

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Lange Methode blockiert UI Sayang Allgemeine Java-Programmierung 11 07.03.2006 22:43
statische Methode per Reflection aufrufen ehli75 Allgemeine Java-Programmierung 2 02.02.2006 13:17
Methode in der main aufrufen, unterschied JApplet und JFrame Gottzilla Desktop-Applikationen und Grafik 3 10.03.2005 10:12


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:13 Uhr.


Powered by vBulletin® Version 3.7.4 (Deutsch)
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45