Avatar billede backupmand Nybegynder
26. juli 2004 - 22:09 Der er 12 kommentarer og
1 løsning

java.lang.Object clone() virker ikke som forventet

.. eller også har jeg gjort det forkert.
Jeg har en klasse, som jeg har ladet implementere clonable - det er også den klasse, jeg gerne vil have en kopi af fordi jeg skal bruge en reference til samme data 2 steder, men sker der ændringer det ene sted må det ikke få indflydelse på layoutet det andet sted. Altså sådan umiddelbart. .....

Det er kort sagt en klasse indeholdende noget layout kode på et JPanel, som jeg skal bruge 2 steder. Ved opstart af min app, laver jeg en instans af den klasse med gui koden i. KLassen tilføjer nogle knapper til et panel og lægger dette panel i et scrollpane.

I den ene klasse, hvor jeg skal bruge min layout kode er der ikke noget på mit panel, fordi den anden klasse (der også skal bruge koden) har hugget hele objektet.

Kan det ikke nok lade sig gøre at lave en clone() af gui klassen,
så jeg undgår reduntant kode et af stederne.

Håber jeg fik forklaret det godt nok.
Avatar billede arne_v Ekspert
26. juli 2004 - 22:11 #1
Du skal selv lave en clone metode i din klasse som laver en clone
af de felter klassen indeholder.
Avatar billede backupmand Nybegynder
26. juli 2004 - 22:11 #2
Det ser nogenlunde sådan ud ved opstart (jeg kan ikke poste hele koden her, da der er rigtigt meget).

MenuDatabaseButtons mdbClone1=(MenuDatabaseButtons)mdb.clone();
MenuDatabaseButtons mdbClone2=(MenuDatabaseButtons)mdb.clone();
jr=new JComponentRepository(this,mdbClone1);
cf=new Configuration(this,jr,mdbClone2);

Jeg skal også bruge noget data fra jr i Configuration, men jeg har ingen ide om det har indflydelse på layoutet i Configuration. Jeg menter, jeg med de 2 kloner
ville have 2 kloner, men nej ....
Avatar billede arne_v Ekspert
26. juli 2004 - 22:13 #3
Simpelt eksempel:

public class DeepCloneEx {
  public static void main(String[] args) throws Exception {
      MySpecialObj x1 = new MySpecialObj(1, "A");
      MySpecialObj x2 = (MySpecialObj)x1.clone();
      x2.add(2, "B");
      System.out.println(x1);
      System.out.println(x2);
  }
}

class MySpecialObj implements Cloneable {
  private int i;
  private StringBuffer sb;
  public MySpecialObj() {
  }
  public MySpecialObj(int i, String s) {
      this.i = i;
      this.sb = new StringBuffer(s);
  }
  public String toString() {
      return (i + " " + sb);
  }
  public void add(int i, String s) {
      this.i += i;
      this.sb.append(s);
  }
  public Object clone() throws CloneNotSupportedException {
      return new MySpecialObj(i, sb.toString());
  }
}
Avatar billede backupmand Nybegynder
26. juli 2004 - 22:13 #4
ok her er clone metoden
public Object clone()
      {
        try {
      return super.clone();
        }
        catch (CloneNotSupportedException e) {
            throw new InternalError("But we are Cloneable!!!");
          }
      }

Hvis jeg så har et felt der hedder
String hejsa="hejsa";
hvordan clones() det så?
Avatar billede backupmand Nybegynder
26. juli 2004 - 22:14 #5
ups vent lidt vores svar krydser hele tiden hinanden
Avatar billede arne_v Ekspert
26. juli 2004 - 22:15 #6
Object clone er en såkaldt shallow clone. Du ønsker en deep clone.

Fra docs af Object clone:

Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.
Avatar billede arne_v Ekspert
26. juli 2004 - 22:15 #7
:-)
Avatar billede backupmand Nybegynder
26. juli 2004 - 22:16 #8
ja, jeg skal bruge en deep clone
Avatar billede backupmand Nybegynder
26. juli 2004 - 22:21 #9
Det virker. Please svar!
Avatar billede backupmand Nybegynder
26. juli 2004 - 22:23 #10
det vil sige at hvis man ikke laver en deep clone så er det det samme som at
sætte en reference lig en anden?
objekt1 o;
objekt2 o2;
o2=o;
Hvis jeg laver ændringer i o2, sker det samme i o, er det ikke rigtigt?
Avatar billede arne_v Ekspert
26. juli 2004 - 22:23 #11
svar
Avatar billede arne_v Ekspert
26. juli 2004 - 22:27 #12
Ikke helt.

En shallow clone laver faktisk et nyt objekt. Alle felter som er simple data typer
bliver clonet, men alle felter som er objekter cloner man kun referencen.

Med en deep clone så bliver felter som er objekter også clonet.

Med assignment får du bare en reference mere til samme objekt. Uden bogen
form for cloning.

Men hvis klassen kun har felter som er objekter så kan forskellen
synes meget lille. Det er kun med felter som er simple data typer
at du rigtigt kan føle forskellen.
Avatar billede backupmand Nybegynder
26. juli 2004 - 22:29 #13
Aha!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester