Avatar billede di8leva Nybegynder
30. oktober 2002 - 09:56 Der er 14 kommentarer og
2 løsninger

Clone() på ett "unknown" objekt

Jag har en Vector med object som jag vill kopiera till en annan Vector, och de två vectorerna får INTE ha referenser till samma objekt på något stælle.
Men Vectorn kan innehålla alla møjliga objekt, æven sådana som inte ær cloneable och min kod som jag testade ser ut såhær:

    public static final Vector copyVector(Vector source)
    {
        Vector result = new Vector();
        if(source == null)
            return null;

        for(int i = 0; i < source.size(); i++)
        {
            try
            {
                result.add(((Cloneable)source.get(i)).clone());
            }
            catch(CloneNotSupportedException e) { result.add(source.get(i)); }
        }
}

men man får inte gøra så, før cloneable innehåller inte funktionen clone(), och derfor virker det ikke.
några tips?
jag vill inte anvænde mig av instanceof
Avatar billede arne_v Ekspert
30. oktober 2002 - 10:05 #1
Bare undlad at type caste til Cloneable.

Object har metoden clone.

Og den smider en CloneNotSupportedException, hvis ikke
den implemnterer Cloneable.
Avatar billede arne_v Ekspert
30. oktober 2002 - 10:07 #2
Iøvrigt er der ikke nogen problemer med at have to vektorer
som indeholde samme immutable objekt.
Avatar billede di8leva Nybegynder
30. oktober 2002 - 10:08 #3
det virker ikke utan cast, jag vet ikke varfør, men compile siger att "clone() har protected access i object"

och vi måste ha olika objekt, annars får vi problem, tyværr =(
Avatar billede arne_v Ekspert
30. oktober 2002 - 10:09 #4
Iøvrigt som tommelfinger-regel: hvis kopiering af data begynder
at blive kompleks, så bør man overvejde om man kan ændre designet,
så kopiering ikke er nødvendig.
Avatar billede di8leva Nybegynder
30. oktober 2002 - 10:09 #5
testa att skriva new Object().clone() och kompilera.
det virker ikke hos oss...
Avatar billede disky Nybegynder
30. oktober 2002 - 10:12 #6
Det skulle virke på denne måde:

Object temp=source.get(i);
if(temp istanceOf Klasse1)
{
  result.add(((Klasse1)temp).clone());
}
else if(temp istanceOf Klasse2)
{
  result.add(((Klasse2)temp).clone());
}

osv. Så kalder du hver enkelt klasses clone() som skulle lave korrekte kopier af objektet.
Avatar billede arne_v Ekspert
30. oktober 2002 - 10:14 #7
Ups. Det er rigtigt. Object.clone er protected.

Jeg tror. at du skal gå efter at designe dig uden om
problemet.
Avatar billede di8leva Nybegynder
30. oktober 2002 - 10:16 #8
Disky >>> Det ær just instanceOf jag vill unvike, før Object kan vara av minst 30 olika klasser...

Arne >>> Vi har en annan design, men den inneholder mycket kod, och vi ville minska antal kod-rader på ett smart måde.

Jag læmnar spørgsmålet øppet så får vi se om någon har en smart løsning.
Avatar billede disky Nybegynder
30. oktober 2002 - 10:18 #9
Så må du bruge reflection istedet, som performer dårligt.

Men hvis du har MANGE forskellige klasser lyder det som et redesign vil gavne meget, eller lave mere generelle klasser til håndtering af data.
Avatar billede di8leva Nybegynder
30. oktober 2002 - 10:23 #10
disky >>> Reflection ?
Avatar billede arne_v Ekspert
30. oktober 2002 - 10:40 #11
Du kan bruge reflektion til at finde oplysninger om
members og methods i et vilkårlgt objekt.
Avatar billede di8leva Nybegynder
30. oktober 2002 - 11:04 #12
f.eks ?
Avatar billede arne_v Ekspert
30. oktober 2002 - 11:09 #13
Her er et delvist relevant eksempel:

import java.util.HashMap;

public class Test {
    private static Object refclone(Object o) {
        Class declarg[] = new Class[0];
        Object callarg[] = new Object[0];
        try {
            return o.getClass().getMethod("clone", declarg).invoke(o, callarg);
        } catch (Exception ex) {
            return null;
        }
    }
    private static void test(Object o) {
        Object o2 = refclone(o);
        if(o2 != null) {
            System.out.println(o.getClass().getName() + " cloned");
        } else {
            System.out.println(o.getClass().getName() + " not cloned");
        }
        return;
    }
    public static void main(String args[]) {
        String s = new String("abc");
        test(s);
        HashMap hm = new HashMap();
        hm.put("k", "f");
        test(hm);
    }
}
Avatar billede disky Nybegynder
30. oktober 2002 - 11:09 #14
Se java api'en fra www.javasoft.com
Avatar billede davsclaus Nybegynder
30. oktober 2002 - 11:17 #15
Kik på Apache Commons BeanUtils som har en metode til at clone et
object.

http://jakarta.apache.org/commons/beanutils.html

I BeanUtils

cloneBean(java.lang.Object bean)
          Clone a bean based on the available property getters and setters, even if the bean class itself does not implement Cloneable.
Avatar billede arne_v Ekspert
30. oktober 2002 - 11:18 #16
Der er flere problemer med at bruge reflection:
1)  performance er ikke så god
2)  mutable objekter som ikke har en clone bliver
    ikke klonet som de burde
3)  en del objekter har en clone som laver shallow copy
    i.s.f. deep copy (f.eks. HashMap !) hvilket muligvis også
    vil være et problem for dig
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