How to copy objects in java

Asked

Viewed 11,380 times

11

You can make an object copy in Java?

MinhaClasse mc = new MinhaClasse();

MinhaClasse mc2 = mc;

But I wanted to make changes in mc2 unaffected mc.

  • Have you tried using the Java Cloneable class? http://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html

  • Minhaclasse mc = new Minhaclasse(); Minhaclasse mc2 = new Minhaclasse(); would no longer solve

  • wouldn’t solve why I wanted mc2 to have the same mc values, without me having to fill in the fields again manually

3 answers

9


Just overwrite the method Object#clone, but your class needs to implement the interface Cloneable:

By convention, the classes implementing this interface must replace Object.clone (which is protected) by a public method.

Using the example of MinhaClasse used in the question, this would look like this:

public class MinhaClasse implements Cloneable {

    // Atributos e métodos 

    @Override
    public MinhaClasse clone() throws CloneNotSupportedException {
        return (MinhaClasse) super.clone();
    }
}

In this way it would be enough to call the method clone in this way:

MinhaClasse meuObjeto = new MinhaClasse();
MinhaClasse meuOutroObjeto = meuObjeto.clone();

4

The most correct to create copies, duplicate or clone objects is by implementing the method clone() and the interface Clonable. This allows you to define exactly the values that will be copied and even clone object contained in the main object, if applicable.

However, depending on the context, there are other alternatives that may be feasible. For example, if the idea is to just copy a Java Bean with simple attributes, getters and setters, then it is possible the method cloneBean() library Apache Commons Beansutils. There is also the method copyProperties() that copies the attributes of one object to another.

Another option, if the class is serializable, is to run the serialization of the same followed by the deserialization. Ready, you have an exact copy.

Of course it is not recommended to use the two methods mentioned above for such a simple case, but they can be useful for developing frameworks or very specific functionalities.

One of the scenarios where I’ve used this is in a system that literally had hundreds of constantly changing Java Beans. It was not feasible to create and keep up to date the method clone() in all classes.

  • I’m sorry to disagree, but the clone method is not "the right method" for creating copies. Everything you say is an advantage of the clone method is possible with the copy builder and without the need to implement an interface. I will not vote against because I think the suggestion to use cloneBean is interesting. :)

  • 1

    @Brune The language has a very clear and defined pattern to create copies, the method clone. Just because it is possible to do otherwise does not mean that there is no pattern.

  • 1

    @Actually, from a Project Standards point of view, the builder is not a good practice because you get too dependent on the implementation. A method Factory would be more interesting, but from the point of view of abstraction and polymorphism, clone is the most generic. Depending on the application of the copies, the clone allows to apply the project pattern Prototype, what is not possible with a builder.

3

Yes, just define the Constructor method

class MinhaClasse {
  private String str;

  public MinhaClasse (MinhaClasse outro) {
    this.str= outro.str; // tens acesso directo
  }
}

All Objects have a clone method that by default allows copying objects. Good practice dictates that you should define your copying method.

After setting this method it is simple to copy objects. You can simply do the following:

MinhaClasse mC = new MinhaClasse();
....(fazer algo com o objecto)
mc.Update();

MinhaClasse mC2(mc);
....(fazer algo com o objecto)
mC2.Update()  <- esta alteração apenas irá afectar mC2!

In response to your comment. If your Minhaclasse class has as members other classes than primitive type (int, string, ...) then those classes must also have defined copy constructors. For example.

class ClasseA {

   private ClasseB b;
   private String str;

   ClasseA (ClasseA outro) {
      this.b(outro.b) (aqui tens que garantir que a ClasseB possui um constructor de copia ou método =)  
      this.str= outro.str; // tens acesso directo     
      }
}

EDIT:

To all those who are suggesting to implement the Cloneable interface and define the clone() method I suggest reading the following articles. Especially the reading of Effective Java:

I leave just one more quote from Josh Bloch

"The Cloneable interface was intended as a mixin interface for Objects to advertise that they Permit Cloning. Unfortunately it fails to serve this purpose ... This is a highly atypical use of interfaces and not one to be Emulated ... In order for implementing the interface to have any Effect on a class, it and all of its superclasses must Obey a fairly Complex, unenforceable and largely undocumented Protocol"

  • 1

    What to do when the class references other classes within it? References are still pointing to the same objects. I’ll have to program the recursive clone?

  • Yes, you should do it recursively and it will be a bit of a hassle. Have you ever stopped to take a closer look at your business to see if a copy of an object is really necessary? There are no other alternatives in your design to avoid having to?

  • In my project, I’ll have to send an object via json, but there’s something about that object that I didn’t want to send. So I thought of copying the object, deleting what I didn’t want to send, and doing the json of that copy. I’ll think of another way to do this, but I think I’ll have to copy the data I don’t want to send, delete from the class and put it back after the creation of json

  • 2

    It’s not easier to give one new in an object and only set the properties you need from the original object? Or filter in the creation of json?

  • 2

    The Effective Java book is very good, but just because the author cites some problems and disadvantages of using a certain functionality of the language, it does not mean at all that it should not or cannot be used in several simpler scenarios, as is the case with simple Java Beans. Other chapters of the book do the same, entering into very interesting and deep discussions as in the case of the different possible implementations of the Singleton standard. The important thing is to understand that every approach has its advantages and disadvantages.

  • 2

    One of the big problems of cloning with constructor is the high coupling with implementation. And if polymorphic implementations are made, the same exact problems cited by the author can occur.

  • @utluiz, first of all thank you for the comment. It is important when we can discuss these kinds of issues here and we can participate in this exchange of information. In the comment I made to your answer, I mentioned it myself, that for example cloneBeans is a good alternative to Shallow-Cloning. However, I stand by my opinion. The cloneable interface has flaws in its design, just search for this internet outside that there is no shortage of articles to indicate the same and suggest alternatives. For me the problem is just saying that the best method for copying objects is clone(), that’s all.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.