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



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

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

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用于调用类层次结构中更高级别的实现,但仍在执行super调用的对象上调用。


编辑 2

因为这涉及到clone(),这本身并不大,应该不惜一切代价避免。您可以在互联网上阅读原因。

clone()的规范实现实际上要求类的类层次结构中的所有类提供clone()的规范实现。clone()的实现应该从调用super.clone()开始,因为我们期望父类将克隆该类的所有成员并分配它们并返回对象。然后,子类的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(): %sn", this.getClass().getSimpleName());
A clone;
try {
clone = (A) super.clone();
System.out.printf("Class of clone in A.clone(): %sn", clone.getClass().getSimpleName());
System.out.printf("Value of member1 in A.clone(): %sn", 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(): %sn", this.getClass().getSimpleName());
B clone = (B) super.clone();
System.out.printf("Class of clone in B.clone(): %sn", clone.getClass().getSimpleName());
System.out.printf("Value of member2 in B.clone(): %sn", 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(): %sn", this.getClass().getSimpleName());
C clone = (C) super.clone();
System.out.printf("Class of clone in C.clone(): %sn", clone.getClass().getSimpleName());
System.out.printf("Value of member3 in C.clone(): %sn", 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相同类型。

Object 中的克隆方法是默认实现。

最新更新