如何克隆一个你不知道类型的对象?

f1w*_*ade 1 java object cloning

在代码中更容易解释,所以在这里

Object anObj;
anObj = new MyObj();
anObj = new Rectangle();
anObj.clone();//this doesnt exist because its on the root Object class
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我可以用什么来代替 Object.clone() 方法?

----------------------- 额外信息 ------------------------- -----

我已经添加了额外的信息,但它似乎已经出现在所有答案的中间,所以它再次出现以便可以阅读。

嗨,所有这些对克隆或复制的主题都非常有帮助,我现在需要考虑一下。但他们对最初的问题没有帮助。也许我提供的更多信息将帮助您了解我的追求。

我正在覆盖每个对象的克隆,并添加完全克隆对象所需的所有其他克隆和复制方法,这包括添加自定义方法来复制缓冲图像。IE:-

public Object clone() {//i copied from 'thelost's answer
    try { 
        CloningExample copy = (CloningExample)super.clone(); 
        copy.names = (LinkedList)names.clone(); 
        return copy; 
    } catch (CloneNotSupportedException e) { 
        return null; 
    } 
}
Run Code Online (Sandbox Code Playgroud)

但是我的类中有一个变量是一个对象,但是因为它包含不同类型的各种其他对象,所以我的每个类型都有一个 clone 方法,但是没有检查它是否是我的每个类型,然后调用 clone()我的类型会很长,因为我有很多类型,我看不到如何轻松复制或克隆对象。有没有办法让我只写一个像这样的静态方法?

static findTypeAndCopy(Object thisobj){ 
    if(thisobj==null) 
        return null;

    if(thisobj instanceOf MyObj1){ 
        return ((MyObj1)thisobj).clone(); 
    }else if(thisobj instanceOf MyObj2){ 
        return ((MyObj2)thisobj).clone(); 
    ... 
    etc
}
Run Code Online (Sandbox Code Playgroud)

???

pol*_*nts 5

您似乎已经意识到Cloneable在 Java 中已损坏。

以下是对《Effective Java 2nd Edition》作者Josh Bloch 的采访中的一些引述:

如果你读过我书中关于克隆的文章,特别是如果你在字里行间读过,你就会知道我认为它clone被深深地打破了。有一些设计缺陷,其中最大的是Cloneable接口没有clone方法。这意味着它根本不起作用:制作某物Cloneable并不能说明您可以用它做什么。相反,它说明了它可以在内部做什么。它说如果通过super.clone重复调用它最终调用了Objectclone方法,则此方法将返回原始字段的副本。

但是它并没有说明您可以对实现该Cloneable接口的对象做什么,这意味着您不能进行多态clone操作。

以下是这本书中的一些引述,第 11 项:clone明智地覆盖

[...] 您最好提供对象复制的替代方法,或者干脆不提供该功能。

[...] 对象复制的一种很好的方法是提供复制构造函数复制工厂。复制构造函数只是一个构造函数,它接受一个参数,其类型是包含构造函数的类:

public Yum(Yum yum);
Run Code Online (Sandbox Code Playgroud)

复制工厂是static复制构造函数的工厂模拟:

public static Yum newInstance(Yum yum);
Run Code Online (Sandbox Code Playgroud)

相关问题


替代方案:Cloneable2.0

如果你真的坚持拥有一个Cloneable不会被破坏的 -like 功能,你可以写这样的东西(为额外的爵士乐而生成):

public class DupableExample {

    interface Dupable<T> {
        T dup();
    }   
    static class Sheep implements Dupable<Sheep> {
        Sheep(Sheep sheep) { }
        @Override public Sheep dup() {
            return new Sheep(this);
        }
    }
    public static void main(String[] args) {
        Dupable<?> dupable = new Sheep(null);
        System.out.println(dupable);
        System.out.println(dupable.dup());
        
        // no cast needed
        Sheep dolly2 = new Sheep(null).dup();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出应该是这样的(如 ideone.com 所示):

DupableExample$Sheep@{some hexadecimal code}
DupableExample$Sheep@{a different hexadecimal code, in all likelyhood}
Run Code Online (Sandbox Code Playgroud)

所以现在给定 any Dupable<T>,您可以调用T dup()它以获得您期望的副本。

这只是一个概念验证:在实际实现中,您的复制构造函数/复制工厂/任何复制机制实际上都会实现复制逻辑,并且Dupable<T>将是public顶级interface.