首页 > 解决方案 > 为什么 java.lang.Object 类的 clone() 方法没有主体?

问题描述

这个平台上有很多关于 Object 类的 clone() 方法的问题。每个人的回答都不一样。关于为什么 clone() 受到保护有很多问题。有人说..

  1. clone() 是受保护的,所以我们必须提供自己的 clone() 并从中间接调用 Object.clone()。
  2. clone() 在 java.lang 包之外受到保护,我们可以直接在子类中访问此方法,也可以仅使用子类 Object 访问此方法。
  3. 不能在不可克隆的对象上调用 clone,因此它不会被公开。

现在这是我的问题。

  1. 如果上述第二点是正确的,那么我们如何直接访问子类中的 clone()
  2. 什么是不可克隆对象
  3. 在克隆的情况下需要在子类中覆盖克隆()。而另一个包的受保护成员,我们可以通过直接继承其父类来访问另一个包。
  4. 为什么 Object.clone() 没有正文部分。

    受保护的本机对象 clone() 抛出 CloneNotSupportedException;

标签: javaclone

解决方案


如果上述第二点是正确的,那么我们如何直接访问子类中的 clone() 。

它是正确的。

像这样:

public class Foo implements Cloneable {  
    public Foo copy() {
        return super.clone();  // or just `clone()`
    }
}

关键是类的方法可以调用protected其超类中的方法。请注意,如果要启用in的默认实现,则Foo需要。但是你不必启用它,即使启用了也不必使用它;见下文。implement Cloneableclone()java.lang.Object

什么是不可克隆的对象。

它们是您无法clone()(成功)调用的对象。具体含义取决于上下文:

  • 可能是没有public克隆方法的对象,您不能调用该方法protected

  • 可能是(非公开)克隆方法不起作用;例如,因为该类没有implement Cloneable或扩展了一个。

clone()在克隆的情况下需要在子类中覆盖什么。而另一个包的受保护成员,我们可以通过直接继承其父类来访问另一个包。

覆盖有三个不同的原因clone()

  1. 使clone()其他无法访问它的类可以访问。也就是说,任何不在同一个包中且不扩展此类的类。

  2. 要更改clone()方法的行为:

    • 你不必打电话super.clone()。您可以随心所欲地实现克隆行为。
    • 你可以在调用后对克隆做一些事情super.clone()
  3. 覆盖返回类型,这样您就不需要转换clone(). (的返回类型Object::cloneObject。)

为什么 Object.clone() 没有正文部分。

你注意到native修饰符了吗?本机方法没有主体。

的克隆行为java.lang.Object是在本机代码中实现的。它正在做普通Java代码无法完成的事情。(或者使用 Java 反射,就此而言。)


推荐阅读