在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
.
相同类型的对象
我真的对此感到困惑(也许这对您来说听起来很奇怪,对此感到抱歉)。例如,如果我有 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
.