可克隆接口有什么意义?

Dan*_* K. 3 java interface

Java中的可克隆接口有什么意义?java中的核心对象有一个clone()方法.你能不能覆盖那个方法?:

@Override
public Foo clone(){
    return new Foo(this.x, this.y);
}
Run Code Online (Sandbox Code Playgroud)

请解释为什么要使用该界面.我已经知道了克隆对象的细节.我只是不明白你为什么要使用这个界面.

dka*_*zel 6

要回答第一个问题,必须实现该方法的Clonable接口,clone()因为Object的clone会检查接口是否已实现,否则会引发异常.

使用clone()是一个坏主意.这是Java中最初没有成功的想法之一.有一些设计问题,包括它通常是浅拷贝.如果要制作对象的副本或深层副本,最好创建复制构造函数或复制方法,而不使用克隆.正确使用clone()很难.

如果您真的想使用clone(),请阅读此博客文章,其中说明了如何使用clone().基本上使用时要记住5点clone():

1)克隆方法用于在Java中创建对象的副本.为了使用clone()方法,类必须实现java.lang.Cloneable接口并从java.lang.Object中覆盖protected clone()方法.如果该类没有实现Cloneable接口,则调用clone()方法将导致CloneNotSupportedException.

2)在Java中克隆Object时没有调用构造函数.

3)Java中clone()方法的默认实现提供了对象的"浅拷贝",因为它通过创建新实例然后通过赋值复制内容来创建Object的副本,这意味着如果你的Class包含一个可变字段,那么两个原始对象和clone将引用相同的内部对象.这可能很危险,因为对该可变字段所做的任何更改都将反映在原始对象和复制对象中.为了避免这种情况,重写clone()方法以提供对象的深层副本.

4)按照惯例,应该通过调用super.clone()方法获得实例的克隆,这将有助于保留clone()方法创建的对象的不变量,即clone!= original和clone.getClass()== original.的getClass().虽然这些并不是Javadoc中提到的绝对要求.

5)实例的浅拷贝很好,直到它只包含原语和Immutable对象,否则,你需要修改super.clone返回的一个或多个对象的可变字段,然后再将它返回给调用者.