views:

96

answers:

4

I've seen defensive copies coded like this

void someMethod(Date d) {
    myDate = new Date( d.getTime() );
}

But that doesn't make sense to me, isn't there a way in Java to create an Identical copy in memory of that object? I've read the clone() will not work in all instances, but I don't understand why

+4  A: 

I could try to answer this, but I'd just be plagiarizing Josh Bloch, so here's a link instead:

http://www.artima.com/intv/bloch13.html

Scott Smith
nice link. So in few words: Using Cloneable can lead to copies with shared states.
RocketSurgeon
@RocketSurgeon: So can a badly written copy constructor...
Uri
@jboyd - How about accepting this answer? :-)
Scott Smith
A: 

There is no simple way to make an identical copy that always works.

Clone was supposed to do that, but it is not implemented by all classes and thus more or less broken.

Another approach would be to serialize/deserialize, but serialization is also not supported by all classes.

Thilo
And using serialization would be horribly inefficient.
Software Monkey
+2  A: 

clone() is only implemented meaningfully in some classes, because there are a lot of decisions involved in cloning that the JVM or the compiler doesn't make for you (e.g., shallow vs. deep copying). Some would also argue that the whole concept in Java is broken and therefore rarely used.

The end result, however, is that many classes cannot be cloned. In these cases, a user clones them by generating and initializing one object based on the other.

However, the Date class implements cloneable, so there isn't really a benefit in this specific case compared to just using the "copy constructor".

One situation where cloning is preferable is when you are working with class hierarchies. Imagine you are representing a mathematical expression as a tree of Expression subtypes, where you reference the "outermost" expression. Let's say that in this case it is a Plus. You would call clone on your reference to an Expression, but what you would really get is a new instance of Plus. With constructors you can't really do that because your Expression could be an interface or an abstract class.

Uri
A: 

From a mobile code security point of view, clone can typically be overridden.

@Override public Date clone() {
    return this; // Ha!
}

Even if you don't care about security, you could imagine a programmer being "clever" causing a bug report in your code.

The expectation that particularly clone will return exactly the same runtime type also causes implementation problems.

Tom Hawtin - tackline