当前位置: 首页 > 知识库问答 >
问题:

当超类不可克隆时,重写Java中的Clone()方法

谭翰海
2023-03-14

如何用clone()方法克隆Java对象

我有一个关于在java中正确实现类的clone()方法的问题。我知道这是不好的做法,但我需要在考试中知道这一点…在上面的讨论中,他们说调用super.clone()-但我不明白如果超级函数没有实现克隆会发生什么。例如,假设我有一个扩展Y的类X。X实现了Cl的,而Y没有。Y的clone()方法应该抛出一个异常。那么在这种情况下我们该怎么办?

我能找到的所有解释都以某种方式假设所有超类都实现了克隆,或者至少我是这么理解的…

编辑:

请查看此代码:

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

类似的代码可以在许多教程中找到。

为什么他们可以使用<code>super。当超类(在本例中为Object)未实现Clonable时,clone()将导致异常。

共有2个答案

程墨竹
2023-03-14

Clonable-接口通常被认为是损坏的(并且不会被修复)。在核心,论点围绕着这样一个事实,即clone()是在Object上定义的方法,而不是接口Clonable的方法。

我根本不建议使用它。更好的解决方案是提供复制构造函数。如果没有能力完全重新创建父类对象,那么克隆是不可能的。

重构提供的代码将导致类似于以下内容的结果:

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();  
    }
}

类型转换是多余的,因为方法返回Object

辛麻雀
2023-03-14

如果您有此结构:

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上的Clonable接口是默认clone()实现的机制的指示符,它们应该工作。

可选择的

只要不依赖于< code>clone()的默认实现,您还可以拥有一个带有工作的< code>clone()方法的不可克隆类。

例如:

class Y {
    @Override
    public Y clone() {
        // Don't call super.clone() because it will error
        return new Y(...); // whatever parameters
    }
}

但是,使用此机制,如果您调用<code>super。clone()从Y的子类中获得Y的实例,这可能不是您想要的。

正如其他人指出的那样,< code>Cloneable机制是笨拙和混乱的,通常使用< code>new的复制机制更容易使用。

 类似资料:
  • 如果我克隆了以下类的一个实例,并在实例化时覆盖了一个方法,克隆会有被覆盖的方法吗?我在https://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html和https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone()中没有找到任何关于这种行为的内容。

  • 我对在我想要克隆对象的类中重写克隆方法感到困惑。 因为Java中的每个类都是从Object扩展而来的,所以它应该有clone方法,但是我们仍然被迫重写clone。为什么要求? 另外,我在一些地方阅读了重写克隆对象并将其公之于众的内容。我想知道,为什么会这样? 欢迎提供所有答案。

  • 克隆当前的合约实例对象。 调用: myContract.clone() Clones the current contract instance. 参数: 无 返回值: Object: 克隆得到的新合约实例 示例代码: var contract1 = new eth.Contract(abi, address, {gasPrice: '12345678', from: fromAddress})

  • 问题内容: 我需要在我的没有超类的对象中实现一个深层克隆。 处理超类(即)引发的检查的最佳方法是什么? 一位同事建议我按以下方式处理: 对我来说,这似乎是一个不错的解决方案,但我想将其扔给StackOverflow社区,以查看是否有我可以提供的其他见解。 问题答案: 你绝对必须使用吗?大多数人都同意是坏的。 如果你已经阅读了我书中有关克隆的内容,尤其是你在两行之间阅读的话,你会知道我认为它clon

  • Threejs大多数对象都有克隆.clone()和复制.copy()两个方法,点模型Points、线模型Line、网格网格模型Mesh一样具有这两个方法。 复制方法.copy() A.copy(B)表示B属性的值赋值给A对应属性。 var p1 = new THREE.Vector3(1.2,2.6,3.2); var p2 = new THREE.Vector3(0.0,0.0,0.0); p2

  • 有一个带有一些功能的接口。基类实现接口。然后在子类中重写函数。 但是@override给出了编译器错误“方法不从其超类重写方法” 问题:在子类中,如何覆盖基类中实现的接口函数? }