简体   繁体   English

在 Java 中,super.clone() 方法如何“知道”哪个 object 调用了它?

[英]In Java, how super.clone() method “knows” which object has called it?

I'm really confusing with this (maybe it sounds strange to you, sorry about that).我真的对此感到困惑(也许这对你来说听起来很奇怪,对此感到抱歉)。 For example, if I have class A and override clone method and in body I have super.clone().. It calls clone() method from Object class, and my question is HOW clone method in Object class knows which object to clone.. Maybe I do not understand well super (I know when use this that you know to use current object of class). For example, if I have class A and override clone method and in body I have super.clone().. It calls clone() method from Object class, and my question is HOW clone method in Object class knows which object to clone.可能我不是很懂超(我知道用这个的时候就知道用当前的object之类的)。

All Java classes, if they do not define an explicit extends , extend Object .所有 Java 类,如果它们没有定义明确的extends ,则扩展Object A call to super.clone() or really any call to super.someMethod() will call the implementation of that method one link up in the class hierarchy instead of calling the implementation of that method defined in the class.super.clone() super.someMethod()任何调用都将调用 class 层次结构中的一个链接的该方法的实现,而不是调用 class 中定义的该方法的实现。

Take for instance举个例子

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

and

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()");
    }
}

This:这个:

new A().someMethod();

will print A.someMethod();将打印A.someMethod();

And this:和这个:

new B().someMethod();

Will print将打印

A.someMethod()
B.someMethod()

EDIT 1编辑 1

A slightly more complex example:一个稍微复杂一点的例子:

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();
    }
}

Will print B.someMethod()将打印B.someMethod()

super is used to call an implementation higher up the class hierarchy but it is still called on the object that is doing super call. super用于调用 class 层次结构更高的实现,但它仍然在执行super调用的 object 上调用。


EDIT 2编辑 2

As this pertains to clone() , which is in and of itself not great and should be avoided at all costs.因为这与clone()相关,它本身并不是很好,应该不惜一切代价避免。 You can read up on the reasons why all over the internet.您可以阅读整个互联网的原因。

A canonical implementation of clone() really requires all classes in the class hierarchy of a Class to provide a canonical implementation of clone() . clone()的规范实现确实需要 Class 的 class 层次结构中的所有类来提供clone()的规范实现。 The implementation of clone() should start with a call to super.clone() because we expect that the parent class will do the cloning of all that class's members and assign them and return the object. clone()的实现应该从调用super.clone()开始,因为我们希望父 class 将克隆该类的所有成员并分配它们并返回 object。 Then the child class's clone() implementation should then copy its member fields and assign them to the clone.然后子类的clone()实现应该复制其成员字段并将它们分配给克隆。

We can see this happening in the expanded example我们可以在扩展示例中看到这种情况

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();
    }
}

And when we run it we get this:当我们运行它时,我们得到:

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

Here we can see that this is always C and so is the clone.在这里我们可以看到this总是 C 和克隆。 Going all the way up the stack and calling super.clone() in A calls Object.cone() which will allocate and object of the same type as this .一直向上堆栈并在A中调用 super.clone( super.clone()调用Object.cone() ,它将分配与this相同类型的 object 。

The clone method in Object is a default implementation. Object 中的克隆方法是默认实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM