Copier un objet en Java

j'ai un objet que je dois copier en Java. J'ai besoin de créer une copie et d'exécuter quelques tests sans changer l'objet original lui-même.

je suppose que j'avais besoin d'utiliser la méthode clone (), mais c'est protégé. Ayant fait quelques recherches sur le net, je peux voir que cela peut être remplacé par une méthode publique dans ma classe. Mais je ne trouve pas d'explication sur la façon de le faire. Comment cela pourrait-il être fait?

Aussi, est-ce la meilleure façon de la réalisation de ce dont j'ai besoin?

19
demandé sur mayooran 2009-01-24 13:40:47

7 réponses

une autre option en utilisant le constructeur de copie (de pratiques Java ):

public final class Galaxy {

    public Galaxy (double aMass, String aName) {
        fMass = aMass;
        fName = aName;
    }

    /**
    * Copy constructor.
    */
    public Galaxy(Galaxy aGalaxy) {
        this(aGalaxy.getMass(), aGalaxy.getName());
        //no defensive copies are created here, since 
        //there are no mutable object fields (String is immutable)
    }

    /**
    * Alternative style for a copy constructor, using a static newInstance
    * method.
    */
    public static Galaxy newInstance(Galaxy aGalaxy) {
        return new Galaxy(aGalaxy.getMass(), aGalaxy.getName());
    }

    public double getMass() {
        return fMass;
    }

    /**
    * This is the only method which changes the state of a Galaxy
    * object. If this method were removed, then a copy constructor
    * would not be provided either, since immutable objects do not
    * need a copy constructor.
    */
    public void setMass( double aMass ){
        fMass = aMass;
    }

    public String getName() {
        return fName;
    }

    // PRIVATE /////
    private double fMass;
    private final String fName;

    /**
    * Test harness.
    */
    public static void main (String... aArguments){
        Galaxy m101 = new Galaxy(15.0, "M101");

        Galaxy m101CopyOne = new Galaxy(m101);
        m101CopyOne.setMass(25.0);
        System.out.println("M101 mass: " + m101.getMass());
        System.out.println("M101Copy mass: " + m101CopyOne.getMass());

        Galaxy m101CopyTwo = Galaxy.newInstance(m101);
        m101CopyTwo.setMass(35.0);
        System.out.println("M101 mass: " + m101.getMass());
        System.out.println("M101CopyTwo mass: " + m101CopyTwo.getMass());
    }
} 
28
répondu ecleel 2014-01-28 20:35:43

Il y a deux approches populaires. L'une est de fournir une méthode clone comme vous l'avez mentionné, comme ainsi.

public class C implements Cloneable {
    @Override public C clone() {
        try {
            final C result = (C) super.clone();
            // copy fields that need to be copied here!
            return result;
        } catch (final CloneNotSupportedException ex) {
            throw new AssertionError();
        }
}

faites attention aux champs de copie ... ici!" partie. Le result initial n'est qu'une copie superficielle, ce qui signifie que s'il y a une référence à un objet, l'original et le result partageront le même objet. Par exemple, si C contient private int[] data vous auriez probablement souhaitez copier.

...
final C result = (C) super.clone();
result.data = data.clone();
return result;
...

notez que vous n'avez pas besoin de copier des champs primitifs, car leur contenu est déjà copié, ou des objets immuables, car ils ne peuvent pas changer de toute façon.

la deuxième approche consiste à fournir un constructeur de copies.

public class C {
    public C(final C c) {
        // initialize this with c
    }
}

ou une usine de copie.

public class C {
    public static C newInstance(final C c) {
        return new C(c);
    }

    private C(final C c) {
        // initialize this with c
    }
}

les Deux approches ont leurs propriétés respectives. clone est agréable parce que c'est une méthode, donc vous n'avez pas à connaître le type exact. En fin de compte, vous devrait toujours finir avec une copie" parfaite". Le constructeur de copie est agréable parce que l'appelant a une chance de décider, comme peut être vu par les Collections Java.

final List c = ... 
// Got c from somewhere else, could be anything.
// Maybe too slow for what we're trying to do?

final List myC = new ArrayList(c);
// myC is an ArrayList, with known properties

je vous recommande de choisir l'une ou l'autre approche, celle qui vous convient le mieux.

j'utiliserais les autres approches, comme la copie réflective ou la sérialisation/désérialisation immédiate, dans les essais unitaires seulement. Pour moi, ils se sentent moins appropriés pour le code de production, principalement en raison de la performance préoccupation.

20
répondu Ronald Blaschke 2009-01-24 16:12:55

quelques options:

  • vous pouvez implémenter Cloneable pour votre objet et mettre clone() méthode en public. Voir l'explication complète ici: http://www.cafeaulait.org/course/week4/46.html

    Cependant, cela produit une copie superficielle et pourrait ne pas être quelque chose que vous voulez.
  • vous pouvez sérialiser et deserialiser votre objet. Vous devrez implémenter l'interface Serializable pour l'objet et tous ses champs.
  • vous pouvez utiliser XStream pour effectuer la sérialisation via XML - vous n'aurez pas à mettre en œuvre quoi que ce soit ici.
13
répondu Yoni Roit 2013-02-27 11:53:26

pour la sérialisation du code test est peut-être la réponse la plus sûre, surtout si l'objet est déjà sérialisable, essayez Apache Commons SerializationUtils pour une implémentation.

8
répondu Gareth Davis 2018-02-16 04:39:06

vous pouvez utiliser org.Apache.commun.lang3.Classe SerializationUtils pour le clonage d'objet, - Class devrait mettre en œuvre L'interface sérialisable.

  • nom de classe copyobject = SerializationUtils.clone (classobjecttopy)

SerializationUtils.clone est également pris en charge sur Google App Engine instance

3
répondu A.G 2017-06-01 04:48:32

il y a plusieurs façons de copier un objet en java(superficiel ou profond).

Cette réponse vous aidera.

2
répondu Chandra Sekhar 2017-05-23 12:03:04

Joshua Bloch a des choses intéressantes à dire au sujet de clonable . Selon la taille/construction de l'objet, j'ajouterais un constructeur de copie à l'objet, ou sérialiserais/deserialiserait en utilisant l'une des solutions mentionnées ci-dessus.

1
répondu Brian Agnew 2009-01-24 13:51:04