Question

I have a question regarding the clone() method in Java. First of all, I do know the clone method is broken and all the rest but we're studying this topic at school and I want to get a tight grip of it (even though it may not be the most effective way of doing things).

Let's assume I'm in a situation like this:

public class A implements Cloneable {
    private int a;
    private int b;

    // constructors, methods, etc.

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

public class B extends A {
    private String c;
    private String d;

    // constructors and all the rest

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

Now, if in my main() I had something like:

B test1 = new B();
B test2 = (B) test1.clone();

I know from experience that the clone() method would make a copy of all the values of test1; in fact, I can access and modify int a, int b, String c and String d thanks to the appropriate get/set methods.

What I don't really get is why this all works that way. I mean: when I run the clone() from B it makes a call to the clone() from A, which in turn makes a call to Object's clone() which returns an object that is a shallow copy of test1. Such object is then returned to A's clone() which returns it to B's clone() which returns it.

Now, where does this copying happen and what is copied? A and B's clone() don't actually do anything (or technically any copying). B's method just makes a call to A's method which in turn makes a call to Object's. The first answer to this question I found yesterday reinforces my belief about the necessity of A and B's clone() methods, stating that in that particular case (which happens to be the same as mine), B's clone() wouldn't even be necessary at all.

Fair enough, this means Object's clone() is the one that does all the copying. Point now is: how does Object's clone() see all of the necessary fields?

I humbly hypothesized that it was because Object is a superclass of B, but that kind of thinking doesn't really stand. In fact, A is a superclass of B too but I can't access B's private fields if it wasn't for the get/set methods I put inside B. And Object's clone() surely doesn't work based on my get/set methods.

  • Is there something I'm missing here or am I just trying to understand something which is considerably over my head?
  • Is the clone() method in Object some sort of "special" method or something?
  • Can I take it as an axiom from now on that Object's clone() makes a shallow copy of all the fields of an Object? (being them private or only visible in a subclass/superclass or whatever else...)

(Please provide references if you can. It's not that I don't trust you, it's just that I've searched through all my textbooks and online too and I'd really like to know where to look the next time I have a question like this! ;) )

Was it helpful?

Solution

The javadoc of clone() explains what Object.clone() does:

The method clone for class Object performs a specific cloning operation. First, if the class of this object does not implement the interface Cloneable, then a CloneNotSupportedException is thrown. Note that all arrays are considered to implement the interface Cloneable. Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.

The clone() method is a native method (just look in the sources). It's implemented in native code, by the JVM, which of course has access to all the state of the object being cloned. Note that even Java code using reflection also has access to all the state, even private, of any object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top