当超类不可克隆时覆盖 Java 中的 Clone() 方法
Overriding Clone() method in Java when superclass is not Clonable
How to clone a Java object with the clone() method
我有一个关于在 java 中为 class 正确实施 clone()
方法的问题。
我知道这是不好的做法,但我需要知道这个才能参加考试。
在上面的讨论中,他们说要调用 super.clone()
- 但我不明白如果超级函数没有实现 Clonable 会发生什么。
例如,假设我有一个扩展 Y 的 class X。X 实现了 Clonable 而 Y 没有。 Y 的 clone()
方法应该抛出异常。那这种情况我们怎么办呢?
我能以某种方式找到的所有解释都假设所有超级classes 都实现了 Clonable,或者至少我是这么理解的..
编辑:
请查看此代码:
public class Employee implements Cloneable {
private String name;
public Employee(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Object clone()throws CloneNotSupportedException{
return (Employee)super.clone();
}
public static void main(String[] args) {
Employee emp = new Employee("Abhi");
try {
Employee emp2 = (Employee) emp.clone();
System.out.println(emp2.getName());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
取自这里:https://www.javacodegeeks.com/2018/03/understanding-cloneable-interface-in-java.html
在很多教程中都可以找到类似的代码。
当 superclass(在本例中为 Object
)未实现 Clonable 时,为什么他们可以使用 super.clone()
- 这会导致异常。
Cloneable
-interface is generally regarded as broken (and won't be fixed). At the core, the argument revolves around the fact that clone()
is a method defined on Object
, instead of being a method of the interface Cloneable
.
我根本不推荐使用它。更好的解决方案是提供 copy-constructors。如果没有能力完全重新创建一个父对象-class,那么克隆是不可能的。
重构所提供的代码将导致类似于此的结果:
public class Employee implements Cloneable {
private String name;
public Employee(String name) {
this.name = name;
}
public Employee(Employee that) {
this.name = that.name;
}
public static void main(String[] args) {
Employee emp = new Employee("Abhi");
Employee emp2 = new Employee(emp);
System.out.println(emp2.getName());
}
public String getName() {
return name;
}
}
对您的代码的评论:
public class Employee {
public Object clone()throws CloneNotSupportedException{
return (Employee)super.clone();
}
}
类型转换是多余的,因为方法 returns 和 Object
.
如果你有这样的结构:
class Y {}
class X extends Y implements Cloneable {
@Override
public X clone() {
try {
return (X) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
}
然后在 X
的实例上克隆将正常工作。
它不适用于 Y
的直接实例,因为它们未声明为可克隆。但是 X
上的 Cloneable
接口是默认 clone()
实现机制的指示器,它们应该起作用。
或者
只要不依赖 clone()
.[=24 的默认实现,您也可以使用具有有效 clone()
方法的不可克隆 class =]
例如:
class Y {
@Override
public Y clone() {
// Don't call super.clone() because it will error
return new Y(...); // whatever parameters
}
}
然而,使用这个机制,如果你从Y
的子class调用super.clone()
,你会得到一个实例Y
,这可能不是您想要的。
正如其他人指出的那样,Cloneable
机制笨拙且令人困惑,通常使用 new
的复制机制更容易使用。
How to clone a Java object with the clone() method
我有一个关于在 java 中为 class 正确实施 clone()
方法的问题。
我知道这是不好的做法,但我需要知道这个才能参加考试。
在上面的讨论中,他们说要调用 super.clone()
- 但我不明白如果超级函数没有实现 Clonable 会发生什么。
例如,假设我有一个扩展 Y 的 class X。X 实现了 Clonable 而 Y 没有。 Y 的 clone()
方法应该抛出异常。那这种情况我们怎么办呢?
我能以某种方式找到的所有解释都假设所有超级classes 都实现了 Clonable,或者至少我是这么理解的..
编辑:
请查看此代码:
public class Employee implements Cloneable {
private String name;
public Employee(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Object clone()throws CloneNotSupportedException{
return (Employee)super.clone();
}
public static void main(String[] args) {
Employee emp = new Employee("Abhi");
try {
Employee emp2 = (Employee) emp.clone();
System.out.println(emp2.getName());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
取自这里:https://www.javacodegeeks.com/2018/03/understanding-cloneable-interface-in-java.html
在很多教程中都可以找到类似的代码。
当 superclass(在本例中为 Object
)未实现 Clonable 时,为什么他们可以使用 super.clone()
- 这会导致异常。
Cloneable
-interface is generally regarded as broken (and won't be fixed). At the core, the argument revolves around the fact that clone()
is a method defined on Object
, instead of being a method of the interface Cloneable
.
我根本不推荐使用它。更好的解决方案是提供 copy-constructors。如果没有能力完全重新创建一个父对象-class,那么克隆是不可能的。
重构所提供的代码将导致类似于此的结果:
public class Employee implements Cloneable {
private String name;
public Employee(String name) {
this.name = name;
}
public Employee(Employee that) {
this.name = that.name;
}
public static void main(String[] args) {
Employee emp = new Employee("Abhi");
Employee emp2 = new Employee(emp);
System.out.println(emp2.getName());
}
public String getName() {
return name;
}
}
对您的代码的评论:
public class Employee {
public Object clone()throws CloneNotSupportedException{
return (Employee)super.clone();
}
}
类型转换是多余的,因为方法 returns 和 Object
.
如果你有这样的结构:
class Y {}
class X extends Y implements Cloneable {
@Override
public X clone() {
try {
return (X) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
}
然后在 X
的实例上克隆将正常工作。
它不适用于 Y
的直接实例,因为它们未声明为可克隆。但是 X
上的 Cloneable
接口是默认 clone()
实现机制的指示器,它们应该起作用。
或者
只要不依赖 clone()
.[=24 的默认实现,您也可以使用具有有效 clone()
方法的不可克隆 class =]
例如:
class Y {
@Override
public Y clone() {
// Don't call super.clone() because it will error
return new Y(...); // whatever parameters
}
}
然而,使用这个机制,如果你从Y
的子class调用super.clone()
,你会得到一个实例Y
,这可能不是您想要的。
正如其他人指出的那样,Cloneable
机制笨拙且令人困惑,通常使用 new
的复制机制更容易使用。