简体   繁体   English

在不抛出Java中的CloneNotSupportedException异常的情况下创建克隆函数

[英]Making a clone function without throwing CloneNotSupportedException exception in Java

As part of our homework we are asked to implement an abstract class with a clone method. 作为我们作业的一部分,我们被要求用clone方法实现一个抽象类。 The frame for the function is given: 该函数的框架给出:

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


}

The Shape class has two fields: Shape类有两个字段:

private Point location;
private Color color;

At the instructions we're told that the method doesn't throw a CloneNotSupportedException exception, and are also asked why it is so. 在说明中,我们被告知该方法不会抛出CloneNotSupportedException异常,并且还会询问它为什么会这样。 At all the examples we've seen on the internet the clone method does throw a CloneNotSupportedException . 在我们在互联网上看到的所有示例中,clone方法都会抛出CloneNotSupportedException

Would you please point us to the reason why this clone method shouldn't throw that exception. 您能否指出我们为什么这个克隆方法不应抛出该异常的原因。

The method we have written is: 我们编写的方法是:

/**
 * @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;


}

It gives us an error on the (Shape)super.clone() part, saying: 它给我们一个错误的(Shape)super.clone()部分,说:

Unhandled exception type CloneNotSupportedException , how should we create the clone method? Unhandled exception type CloneNotSupportedException ,我们应该如何创建克隆方法?

Your class should implement Clonable interface. 您的类应该实现Clonable接口。

Also you can use Covariant Return Types in order to return Shape/Point instead of Object. 您也可以使用Covariant返回类型返回Shape / Point而不是Object。 This helps you to avoid unnecessary type casts. 这有助于您避免不必要的类型转换。

Unhandled exception type CloneNotSupportedException 未处理的异常类型CloneNotSupportedException

That's because the clone() method in the Object is defined to throw CloneNotSupportedException : 那是因为Objectclone()方法被定义为抛出CloneNotSupportedException

protected Object clone() throws CloneNotSupportedException

See API doc: Object#clone() 请参阅API doc: Object#clone()

To overcome that, you either need to handle it by using a try/catch block or redefine it by adding a throws clause. 要解决这个问题,您需要使用try/catch块来处理它,或者通过添加throws子句来重新定义它。

Update: 更新:

At the instructions we're told that the method doesn't throw a CloneNotSupportedException exception, and are also asked why it is so. 在说明中,我们被告知该方法不会抛出CloneNotSupportedException异常,并且还会询问它为什么会这样。

IMO - IMO -

  1. You are overriding a method in a super class. 您正在覆盖超类中的方法。 Only the return type, method name, and the parameter types are considered as method signature. 只有返回类型,方法名称和参数类型才被视为方法签名。 So, while overriding a method you can omit the throws clause in the subclass even though the method in the superclass has it. 因此,在覆盖方法时,即使超类中的方法具有它,也可以省略子类中的throws子句。
  2. Whenever your class implements the Cloneable interface, it's telling the Object class that it is okay to make a clone of it. 每当你的类实现Cloneable接口时,它告诉Object类可以克隆它。 In such a case, a proper implementation of the clone method should call the super.clone method. 在这种情况下, clone方法的正确实现应该调用super.clone方法。 Now, you can see that it's actually the clone method in the Object class that actually makes the copy. 现在,您可以看到它实际上是Object类中实际生成副本的clone方法。 So, we should leave up to the Object.clone() to throw that CloneNotSupportedException . 因此,我们应该留下Object.clone()来抛出CloneNotSupportedException And it will do so if any class in hierarchy does not implement the Cloneable interface. 如果层次结构中的任何类未实现Cloneable接口,它将执行此操作。

I hope that makes sense. 我希望这是有道理的。

Even though it's kind of vast, in case you want to read about it more. 即使它有点大,如果你想更多地阅读它。 It's explained in Effective Java . 它在Effective Java有所解释。

The reason that other implementations throw the CloneNotSupportedException is that it is part of the existing clone() method of Object . 其他实现抛出CloneNotSupportedException的原因是它是Object的现有clone()方法的一部分 Just because a method is defined to throw the exception does not mean it has to do so. 仅仅因为定义一个方法来抛出异常并不意味着它必须这样做。 When you implement your clone() method on Shape and its derived classes, do not throw the exception. 在Shape及其派生类上实现clone()方法时,不要抛出异常。

The reason that (Shape)super.clone() throws an exception is that this is the default behavior. (Shape)super.clone()抛出异常的原因是这是默认行为。 Implement clone() on Shape. 在Shape上实现clone()。

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

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