1

I have a class TimeLine in my GUI. I have a function where I would like to copy this TimeLine and modify the data in it whithout the TImeLine in my GUI won't be affected.

I've searched some forums and haven't found an easy way because Java let's the references stick. Why isn't there a easy way to create a new Object (TimeLine) that hasn't the reference to the previous one?

Please help my make a copy of this TimeLine object!

Jonas
  • 1,112
  • 5
  • 17
  • 28
  • 1
    related: http://stackoverflow.com/questions/2156120/java-recommended-solution-for-deep-cloning-copying-an-instance/2156367#2156367 – Bozho Aug 11 '11 at 11:50
  • Is it a simple copy only requirement or there is something else where you are facing problem at ? – Santosh Aug 11 '11 at 11:50

5 Answers5

4

The clone() method and Cloneable interface, suggested by other authors here, were created with the incorrect assumption that it would be a good idea to have a generic copying method. The default implementations does a shallow clone of the current object, but you could override it to do a deep clone.

There is no correct, generic way to copy arbitrary objects, what you want to copy depends on the objects involved. For example, immutable objects never need copying (that'd just be a waste of space), while some types of objects can't be copied (how would you copy a FileOutputStream, for example?).

The way I find most elegant is immutable objects with methods that return a copy with just one field changed:

class Pony {
    private final String name;
    private final Color color;
    private final int tailLength;

    // constructors and accessors omitted

    Pony withName(String newName) {
        return new Pony(newName, color, tailLength);
    }

    Pony withColor(Color newColor) {
        return new Pony(name, newColor, tailLength);
    }

    Pony withTailLength(String newTailLength) {
        return new Pony(name, color, newTailLength);
    }
}

// Usage:

Pony tony = new Pony("Tony", Color.DAPPLE, 32);
Pony maurice = tony.withName("Maurice") // Maurice is like Tony, but black.
                   .withColor(Color.BLACK);

Unfortunately, you get a lot of boilerplate this way, and there's no mainstream IDE support either (there may be plugins, though). Related to this is the Builder pattern recommended by Josh Bloch in Effective Java.

gustafc
  • 28,465
  • 7
  • 73
  • 99
3

Instead of clone() you might want to consider writing a copy constructor for your class:

public TimeLine(TimeLine original) {
    this.foo = original.foo;
    this.bar = original.bar;
}

Be careful when copying the value of any reference fields in your class. Be sure whether you want a shallow copy or a deep copy.

rossum
  • 15,344
  • 1
  • 24
  • 38
2

In Java using the operator "=" your are simply copying references to objects. If you want to implement copy by value use clone operation (clone() method of the class Object) or implement your own clone method (overriding the implemented one).

Pay attention that if your class stores other object inside it, these objects should eventually be cloned too (DEEP COPY).

Heisenbug
  • 38,762
  • 28
  • 132
  • 190
  • The '=' operator doesn't copy objects at all, it copies references. You need to reword this. – user207421 Aug 12 '11 at 00:16
  • @EJP : haven't I used the words "copy by reference" ? – Heisenbug Aug 12 '11 at 01:31
  • Partially quoting yourself doesn't change anything. You have used the words 'objects are always copied by reference(using "=" operator)'. They aren't. The '=' operator doesn't 'copy objects by reference' at all. It copies references by value. It's not the same thing. Downvoting. – user207421 Aug 13 '11 at 00:10
  • @EJP: ok..i'll try to modify my answer. But could you explain me what's the difference between "copy objectts by reference" and "copy referencesby value"? I would like to understand that. – Heisenbug Aug 13 '11 at 10:13
  • The difference is that in the first case you are talking about copying objects; in the second case you aren't, you are talking about copying references to objects, in other words you are making those references refer to *different* objects, rather than doing anything to the objects themselves. This shouldn't be hard to understand. Your edit is OK now, de-downvoting. – user207421 Aug 13 '11 at 10:39
1

if you want to copy an object use clone()

if I misunderstood your question please comment

jmj
  • 237,923
  • 42
  • 401
  • 438
  • No you are correct, though i've tried making TimeLine implements Cloneable and added the method : public Object clone().... and when I am trying to make this.timeline = (TimeLine)timeline.clone() i get nullpointerexception. – Jonas Aug 11 '11 at 11:51
  • public Object clone() throws CloneNotSupportedException { return super.clone(); } – Jonas Aug 11 '11 at 11:57
  • 1
    please not, if you want to do a deep copy, you have to overwrite the clone method and implement it by yourself – martin Aug 11 '11 at 11:59
  • So if I dont implement the method, how do I then do .clone() ? – Jonas Aug 11 '11 at 12:03
1

You're looking for the clone method. (I've gone back and forth as to which documentation to cite, that is Wikipedia, it's treatment is more thorough. The Java doc's are more official, of course).

Eg.

MyObject a = new MyObject();
a.setSomething( 2 );
MyObject b = a.clone();

// now b.getSomething().equals(a.getSomething()) (maybe == too, depends on class)
// and b.equals(a)
// b != a
cwallenpoole
  • 79,954
  • 26
  • 128
  • 166