在Java中实现一个克隆函数而不抛出CloneNotSupportedException异常

3

作为我们的作业,我们被要求实现一个带有clone方法的抽象类。函数的框架如下:

/**
 * @effects Creates and returns a copy of this.
 */
public Object clone() {
    // TODO: Implement this method


}
< p > Shape 类有两个字段:

private Point location;
private Color color;

在说明中,我们被告知这个方法不会抛出CloneNotSupportedException异常,并且被问及为什么。在互联网上我们看到的所有示例中,克隆方法确实会抛出CloneNotSupportedException异常。
请您指出这个克隆方法为什么不应该抛出该异常。
我们编写的方法是:
/**
 * @effects Creates and returns a copy of this.
 */

public Object clone() {
    Shape new_shape = (Shape)super.clone();
    new_shape.setColor(this.getColor());
    new_shape.location = (Point)location.clone();
    return new_shape;


}

(Shape)super.clone()部分会出现错误,显示:

未处理的异常类型 CloneNotSupportedException,我们应该如何创建克隆方法?


我已经更新了我的答案。希望能对你有所帮助。 - Bhesh Gurung
3个回答

8

你的类应该实现Clonable接口。

此外,你可以使用协变返回类型来返回Shape/Point而不是Object。这有助于避免不必要的类型转换。


7

未处理的异常类型CloneNotSupportedException

这是因为Object中的clone()方法被定义为抛出CloneNotSupportedException异常:

protected Object clone() throws CloneNotSupportedException

请查看API文档:Object#clone()

为了克服这个问题,您需要使用try/catch块处理它,或者通过添加throws子句来重新定义它。

更新:

在说明中,我们被告知该方法不会抛出CloneNotSupportedException异常,并被问及原因。

在我看来 -

  1. 你正在覆盖超类中的一个方法。只有返回类型、方法名和参数类型被视为方法签名。因此,在覆盖一个方法时,即使超类中的方法具有throws子句,你也可以在子类中省略它。
  2. 每当你的类实现Cloneable接口时,它告诉Object类可以对其进行克隆。在这种情况下,clone方法的适当实现应该调用super.clone方法。现在,你可以看到实际上是Object类中的clone方法实际上进行了复制。因此,我们应该让Object.clone()来抛出CloneNotSupportedException。如果任何继承类没有实现Cloneable接口,它将这样做。

我希望这有意义。

即使它有点广泛,如果你想更多地了解它。它在Effective Java中有解释。


2
其他实现抛出CloneNotSupportedException的原因是它是现有Object的clone()方法的一部分。仅因为定义了抛出异常的方法并不意味着必须这样做。当您在Shape及其派生类上实现clone()方法时,请勿抛出异常。
(Shape)super.clone()抛出异常的原因是这是默认行为。请在Shape上实现clone()方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接