在Java中,如何super.clone()方法"knows"调用了哪个对象呢?

In Java, how super.clone() method "knows" which object has called it?

我真的对此感到困惑(也许这对您来说听起来很奇怪,对此感到抱歉)。例如,如果我有 class A 并覆盖克隆方法,并且在正文中我有 super.clone().. 它从对象 class 调用 clone() 方法,我的问题是如何克隆Object class 中的方法知道要克隆哪个对象.. 也许我不太了解 super(我知道什么时候使用它你知道使用 class 的当前对象)。

Object中的clone方法是默认实现。

所有 Java classes,如果它们没有明确定义 extends,则扩展 Object。对 super.clone() 的调用或对 super.someMethod() 的任何调用都将调用该方法的实现 link 在 class 层次结构中,而不是调用在中定义的该方法的实现class.

为例
public class A {
    public void someMethod(){
        System.out.println("A.someMethod()");
    }
}

public class B extens A {
    @Override
    public void someMethod(){
        super.someMethod(); //call the implementation of someMethod() as defined in A
        System.out.println("B.someMethod()");
    }
}

这个:

new A().someMethod();

将打印 A.someMethod();

还有这个:

new B().someMethod();

将打印

A.someMethod()
B.someMethod()

编辑 1

稍微复杂一点的例子:

public class SuperTest {

    public static class A {

        public void someMethod() {
            System.out.println(
                    this.getClass().getSimpleName()+".someMethod()");
        }
    }

    public static class B extends A {

        @Override
        public void someMethod() {
            super.someMethod();
        }
    }

    public static void main(String[] args) {
        new B().someMethod();
    }
}

将打印 B.someMethod()

super 用于调用 class 层次结构更高层的实现,但它仍然在执行 super 调用的对象上被调用。


编辑 2

因为这与 clone() 有关,它本身并不好,应该不惜一切代价避免。您可以在整个互联网上阅读原因。

clone() 的规范实现确实需要 Class 的 class 层次结构中的所有 classes 提供 clone() 的规范实现。 clone() 的实现应该从调用 super.clone() 开始,因为我们期望父 class 将克隆 class 的所有成员并分配它们和 return对象。然后子 class 的 clone() 实现应该复制其成员字段并将它们分配给克隆。

我们可以在扩展示例中看到这种情况发生

public class SuperCloneTest {

    public static class A implements Cloneable {

        private String member1;

        public A(String value) {
            this.member1 = value;
        }

        @Override
        public Object clone() {
            System.out.println("In A.clone()");
            System.out.printf("Class of `this` in A.clone(): %s\n", this.getClass().getSimpleName());
            A clone;
            try {
                clone = (A) super.clone();

                System.out.printf("Class of clone in A.clone(): %s\n", clone.getClass().getSimpleName());
                System.out.printf("Value of member1 in A.clone(): %s\n", this.member1);

                clone.member1 = this.member1;

                return clone;
            } catch (CloneNotSupportedException e) {
                //A implements Cloneable so we can be sure this won't happen
                throw new UnsupportedOperationException(e);
            }
        }
    }

    public static class B extends A {

        private String member2;

        public B(String value1, String value2) {
            super(value1);
            this.member2 = value2;
        }

        @Override
        public Object clone() {
            System.out.println("In B.clone()");
            System.out.printf("Class of `this` in B.clone(): %s\n", this.getClass().getSimpleName());

            B clone = (B) super.clone();
            System.out.printf("Class of clone in B.clone(): %s\n", clone.getClass().getSimpleName());
            System.out.printf("Value of member2 in B.clone(): %s\n", this.member2);

            clone.member2 = this.member2;

            return clone;
        }
    }

    public static class C extends B {

        private String member3;

        public C(String value1, String value2, String value3) {
            super(value1, value2);
            this.member3 = value3;
        }

        @Override
        public Object clone() {
            System.out.println("In C.clone()");
            System.out.printf("Class of `this` in C.clone(): %s\n", this.getClass().getSimpleName());

            C clone = (C) super.clone();
            System.out.printf("Class of clone in C.clone(): %s\n", clone.getClass().getSimpleName());
            System.out.printf("Value of member3 in C.clone(): %s\n", this.member3);

            clone.member3 = this.member3;

            return clone;
        }
    }

    public static void main(String[] args) {

        new C("value1", "value2", "value3").clone();
    }
}

当我们 运行 它时,我们得到这个:

In C.clone()
Class of `this` in C.clone(): C
In B.clone()
Class of `this` in B.clone(): C
In A.clone()
Class of `this` in A.clone(): C
Class of clone in A.clone(): C
Value of member1 in A.clone(): value1
Class of clone in B.clone(): C
Value of member2 in B.clone(): value2
Class of clone in C.clone(): C
Value of member3 in C.clone(): value3

这里我们可以看到this总是C,克隆也是。一直向上堆栈并在 A 中调用 super.clone() 调用 Object.cone(),它将分配与 this.

相同类型的对象