3

I have an object with a member of type "Object":

class MyObject{
    Object member;

    public Object getObject(){
        return member;
     }

     public void setObject(Object obj){
         member = obj;
     }
}

Is it possible to deep copy MyObject?

yuris
  • 1,109
  • 4
  • 19
  • 33
  • You cannot guarantee deep copy here since Object could be anything. For example, a serialization technique here would fail if not all of the Object members implement Serializable. – Ravi K Thapliyal Jun 11 '13 at 06:43

3 Answers3

10

In its current implementation it is impossible because member can be anything and you cannot make a copy of what you dont know.

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
3

Implement Cloneable marker interface and you can copy of MyObject by clonning.

class MyObject implements Cloneable {
    public Object clone(){
      try {
        return super.clone();
      } catch (CloneNotSupportedException e) {
           return null; 
      }
   }
}

Members also need to be Cloneable other wise it will throw CloneNotSupportedException. ...

MyObject obj = new MyObject();
MyObject obj1 = obj.clone();
Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
0

Even though it is a bean, therefore not immutable, I have an alternative: the freeze/thaw pattern.

If you implement it for your object (which would require that you use a builder class) you could then do:

final MyObject copy = orig.thaw().freeze();

I find it much more convenient than Cloneable or even builders (this is a reversible builder) and use that pattern a lot.

As a bonus, you could make your object NOT being a bean and therefore being immutable. I have a personal profound dislike of beans which is why I came up with that...

And this pattern is recursive too. Let us suppose that you have classes Out and In where In is a member of Out. Let us say that In obeys freeze/thaw. Your code for Out then becomes:

public final class Out
    implements Frozen<Builder>
{
    private final In in;

    private Out(final Builder builder)
    {
        in = builder.in.freeze();
    }

    public static newBuilder()
    {
        return new Builder();
    }

    public In getIn()
    {
        return in;
    }

    @Override
    public Builder thaw()
    {
        return new Builder(this);
    }

    public static final class Builder
        implements Thawed<Out>
    {
        private In.Builder in;

        private Builder()
        {
        }

        private Builder(final Out out)
        {
            in = out.in.thaw();
        }

        public Builder setIn(final In in)
        {
            this.in = in.thaw();
        }

        @Override
        public Out freeze()
        {
            return new Out(this);
        }
    }
}

The net result is that calling copy = orig.thaw().frezze() returns an identical copy with a new instance of in.

fge
  • 119,121
  • 33
  • 254
  • 329