0

Hello everyone I'm writing a Java program where I need to copy the values of an old object into a new one (the two must be separated, if I chance one, the other must not be affected); Once the copy is done the data should be displayed on Jtable, however the 2 object created seems to be linked(if I try to change one the other get modified too)

I suspect the problem is this method :

public void CopiatoreDiArea(Area nuova, Area daCopiare){

    nuova.setNome(daCopiare.getNome());
    nuova.setInter(daCopiare.getInter());
    nuova.setRischioInerente(daCopiare.getRischioInerente());
    nuova.setRischioResiduo(daCopiare.getRischioResiduo());
    nuova.setControlli(daCopiare.getChecklists());
    nuova.setStrategicita(daCopiare.getStrategicita());
    nuova.setRischiosita(daCopiare.getRischiosita());
    nuova.setMediaHpReato(daCopiare.getMediaHpReato());
    nuova.setProbabilitaInerente(daCopiare.getProbabilitaInerente());
    nuova.setEsposta(daCopiare.isEsposta());
    nuova.setStrumentale(daCopiare.isStrumentale());
    nuova.setCommento(daCopiare.getCommento());
    nuova.setCondivisa(daCopiare.isCondivisa());

    if (daCopiare.getNomeCompleto() != null){
        nuova.setNomeCompleto(daCopiare.getNomeCompleto());
    }

    else{
        nuova.setNomeCompleto(daCopiare.getNome());
    }

    if (daCopiare.getInterCompany() != null){
        nuova.setInterCompany(daCopiare.getInterCompany());
    }

    if (daCopiare.getArticoli() != null || daCopiare.getArticoli().size() != 0){
        nuova.setArticoli(daCopiare.getArticoli());
    }

}

If this is the wrong way, how can I accomplish that?

  • How did you create nuova variable before calling the method ? – Aigloun Jun 20 '17 at 09:20
  • 2
    there is concept called deep cloning and shallow cloning and for your case deep cloning is needed here is explaining that [link](https://stackoverflow.com/questions/64036/how-do-you-make-a-deep-copy-of-an-object-in-java) – recursion Jun 20 '17 at 09:26

5 Answers5

2

How do you create the new instance of nuova object? You have to make a new instance of it, if you created the new object with the reference of the oldest they will be linked and every change in the one will be reflected in other.

langeles86
  • 162
  • 1
  • 12
0

If you call the method as following:

CopiatoreDiArea(new Area(), oldArea)

Your code should work as the new 'Area' has all the attributes the other object has without any references being made to the new Area.

Arno C
  • 470
  • 4
  • 18
0

Try this:

public Area CopiatoreDiArea(Area daCopiare){
   Area nuova = new Area();
   nuova.setNome(daCopiare.getNome());
   nuova.setInter(daCopiare.getInter());
   nuova.setRischioInerente(daCopiare.getRischioInerente());
   nuova.setRischioResiduo(daCopiare.getRischioResiduo());
   nuova.setControlli(daCopiare.getChecklists());
   nuova.setStrategicita(daCopiare.getStrategicita());
   nuova.setRischiosita(daCopiare.getRischiosita());
   nuova.setMediaHpReato(daCopiare.getMediaHpReato());
   nuova.setProbabilitaInerente(daCopiare.getProbabilitaInerente());
   nuova.setEsposta(daCopiare.isEsposta());
   nuova.setStrumentale(daCopiare.isStrumentale());
   nuova.setCommento(daCopiare.getCommento());
   nuova.setCondivisa(daCopiare.isCondivisa());

   if (daCopiare.getNomeCompleto() != null){
       nuova.setNomeCompleto(daCopiare.getNomeCompleto());
   }

   else{
       nuova.setNomeCompleto(daCopiare.getNome());
   }

   if (daCopiare.getInterCompany() != null){
       nuova.setInterCompany(daCopiare.getInterCompany());
   }

   if (daCopiare.getArticoli() != null || daCopiare.getArticoli().size() != 0){
       nuova.setArticoli(daCopiare.getArticoli());
   }

 }

And then in your call:

Area nuova = CopiatoreDiArea(daCopiare);
langeles86
  • 162
  • 1
  • 12
0

If you copy primitives (or the special primitive wrapper classes) in Java, the runtime will always do a deep copy of the values. To illustrate this, I show a few examples. See http://jdoodle.com/a/3TL for an online runnable version of the code below:

public class MyClass {
    public static void main(String[] args) {
        int a = 10;
        int b = a;
        b = 20;
        System.out.println(a + " != " + b); 
        // We did not change a when changing b.

        Integer c = 10;
        Integer d = c;
        d = 20;
        System.out.println(c + " != " + d);
        // We did not change c when we changed d, even though they are class instances.
        // This shows that primitive wrappers are handled differently due to
        // autoboxing. 
        // See https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

        MyInteger e = new MyInteger(10);
        MyInteger f = e;
        f.value = 20;
        System.out.println(e + " == " + f);
        // Changing the data contained within f also affected e. The two variables now point to the same instance.

        MyInteger g = new MyInteger(10);
        MyInteger h = new MyInteger(g); 
        h.value = 20;       
        System.out.println(g + " != " + h);
        // We prove that we have two instances, initially containing 
        // the same value but changing their internal values does not 
        // affect each other.
    }

    private static class MyInteger {
        public int value;

        public MyInteger(int value) {
            this.value = value;
        }

        public MyInteger(MyInteger other) {
            this.value = other.value;
        }

        public String toString() {
            return Integer.toString(this.value);
        }
    }
}

From your example, it seems you might be trying to copy complex classes, even lists maybe, and these will always copy a reference only when you use simple assignment.

There are a few options that you could take, for instance the copy constructor that I use above, or alternatively rely on some form of reflection or serialization that does the hard work for you.

Apache Commons Lang has a SerializationUtils class that will run through all internal data in your classes, serialize them into byte format and then try to re-instantiate new versions of the same classes with the serialized data.

The Cloner library makes use of reflection and some special performance cases for known types such as collections and calendars, with some great debugging options.

  • I'll try this way , it seems the best choice , either with the cloner library or the copy constructor , thnx a lot :) –  Jun 20 '17 at 12:17
0

Declare a copy constructor for deep cloning your object

public class Area {
    public Area() { // constructor }
    public Area(Area objectToCopy) {
         setNome(objectToCopy.getNome());
         setInter(objectToCopy.getInter());
         setRischioInerente(objectToCopy.getRischioInerente());
         setRischioResiduo(objectToCopy.getRischioResiduo());
         setControlli(objectToCopy.getChecklists());
         setStrategicita(objectToCopy.getStrategicita());
         setRischiosita(objectToCopy.getRischiosita());
         setMediaHpReato(objectToCopy.getMediaHpReato());
         setProbabilitaInerente(objectToCopy.getProbabilitaInerente());
         setEsposta(objectToCopy.isEsposta());
         setStrumentale(objectToCopy.isStrumentale());
         setCommento(objectToCopy.getCommento());
         setCondivisa(objectToCopy.isCondivisa());

         if (objectToCopy.getNomeCompleto() != null)
             setNomeCompleto(objectToCopy.getNomeCompleto());
         else
            setNomeCompleto(objectToCopy.getNome());
         if (objectToCopy.getInterCompany() != null)
           setInterCompany(objectToCopy.getInterCompany());

         if (objectToCopy.getArticoli() != null || objectToCopy.getArticoli().size() != 0)
         setArticoli(objectToCopy.getArticoli());
    }
}

and then do it calling

Area newArea = new Area(oldArea);
GoGoLander
  • 349
  • 3
  • 12