【问题标题】:Is it possible to use clon() method without overriding it是否可以使用 clon() 方法而不覆盖它
【发布时间】:2020-02-22 06:27:14
【问题描述】:

我的老师遇到了一些麻烦,我们必须在大约一个月内掌握java的概念,他说以下是可能的:

所以在Java中每个类都继承自Object类,这个类为我们提供了protected Object clone()之类的方法,例如:现在假设我们有class Car

// 稍后在 main:

Car mycar=new Car();
//he is saying now that  following is possible:
Car yourCar=(Car) mycar.clone();

但是网上的每一篇文章都说这是不可能的,即使我尝试编译它也是不可能的,首先是因为该方法是受保护的,其次是因为它会抛出一个异常

有什么我想念的吗?

【问题讨论】:

  • 您没有发布课程Car;它会用public 签名覆盖clone() 吗?
  • docs.oracle.com/javase/8/docs/api/java/lang/Object.html#clone-- "首先,如果该对象的类没有实现接口Cloneable,则抛出CloneNotSupportedException"。请显示Car的定义
  • 不,他没有覆盖它,这就是我如此困惑的原因
  • 如果他没有覆盖Car类中的clone()方法,那么这是不可能的,你会收到这些错误。
  • 这很简单:如果Car 实现Cloneable 你的老师是正确的,如果不是你就会有例外并且你的老师是错误的。告诉他,Stackoverflow 是这么说的 :)

标签: java clone


【解决方案1】:

是的,只要类实现 Cloneable,您就可以使用 .clone() 而无需覆盖它。

这是一个例子:

class Car implements Cloneable {
  String name;
  public Car(String n) {
    name = n;
  }

  public static void main(String[] args) throws Exception {
    Car c1 = new Car("Lightning McQueen");
    Car c2 = (Car) c1.clone();
    System.out.println(c2.name);
  }
}

这是类实现 Cloneable 但不覆盖 clone() 时的 default behavior of clone() 的描述:

此方法创建此对象的类的新实例,并使用此对象的相应字段的内容来初始化其所有字段,就像通过赋值一样;字段的内容本身不会被克隆。因此,此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作。

【讨论】:

  • 您不必覆盖clone(),但您必须遵守修改后的protected。从类或子类中调用它,或者通过反射破解它。
  • 但是你做了这个调用 (Car) c1.clone(); car 是一个子类但不在 java.lang 包中,即使你实现了可克隆为什么你可以让调用不应该编译器说方法不可见?
  • clone() 是Object 中的受保护方法,因此它将作为Car extends Object 中的受保护方法继承。因为它是从 Car 类中调用的,所以没问题。
  • 如果您能向我解释以下内容,我将非常感激:既然我们没有覆盖克隆方法,该方法如何知道需要复制哪些字段?我的意思是汽车具有属性字符串:它只会复制引用,但它仍然如何知道该属性是此类的一部分并且需要复制?
  • @Harry Java 平台有一个reflection API,您可以使用它以编程方式列出和访问对象成员。它很可能使用这种功能。
【解决方案2】:

如果Car 公开了public Object clone 的覆盖实现,那么您的老师是正确的。子类可以widen the access to overriden methods,因此clone 可以拥有public 访问权限。您也可以在类本身中调用该方法,即使您不扩大访问范围。

而clone 将抛出一个CloneNotSupportedException if called on a object that hasn't overriden it:

Object类本身并没有实现接口Cloneable,所以在类为Object的对象上调用clone方法会导致在运行时抛出异常。

这解释了为什么您在尝试时会收到异常。您需要在已实现它的对象上调用clone。

【讨论】:

    猜你喜欢
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多