如何克隆您不知道类型的对象? [英] How to clone an Object you dont know the type of?

查看:144
本文介绍了如何克隆您不知道类型的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  Object anObj; 
anObj = new MyObj();
anObj = new Rectangle();
anObj.clone(); //这不存在,因为其在根对象类

在此示例中,我可以使用什么代替Object.clone()方法?



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



我添加了额外的信息,但是似乎所有答案都已消失,因此在这里再次显示出来即可。



大家好这些对于克隆或复制主题确实很有帮助,我现在需要考虑一下。但是他们对最初的问题没有帮助。



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

  public Object clone(){// i从'thelost's answer 
try {
CloningExample copy =(CloningExample)super.clone();
copy.names =(LinkedList)names.clone();
退货副本;
} catch(CloneNotSupportedException e){
返回null;
}
}

但我的班级中有一个变量是对象,但是因为它包含其他各种不同类型的对象,所以我的每个类型都会有一个clone方法,但是缺少检查我的每个类型是否存在,然后在我的类型上调用clone()的时间,只要我有许多类型,我看不到如何轻松地复制或克隆对象。有没有办法我应该像这样写一个静态方法?

  static findTypeAndCopy(Object thisobj){
if(thisobj == null)
返回null;

if(thisobj instanceOf MyObj1){
return((MyObj1)thisobj).clone();
}否则if(thisobj instanceOf MyObj2){
return((MyObj2)thisobj).clone();
...

}

???

解决方案

您似乎已经意识到Java中的 Cloneable 已损坏。 / p>

以下是接受采访时的一些引用Josh Bloch 有效Java第二版的作者:


如果您已阅读该项目关于我的书中的克隆,特别是如果您在两行之间阅读时,您会知道我认为 clone 已被严重破坏。设计存在一些缺陷,其中最大的缺陷是 Cloneable 接口没有 clone 方法。这意味着它根本行不通:制作 Cloneable 的东西并没有说明您可以使用它做什么。相反,它说明了其内部功能。它说,如果反复调用 super.clone ,最终会调用 Object clone 方法,此方法将返回原始字段的副本。



但是它并没有说明您可以对实现 Cloneable 接口的对象执行的操作意味着您不能执行多态 clone 操作。


书中的一些引语,项目11:明智地覆盖 clone


[...]最好提供对象复制的替代方法,或者根本不提供此功能。



[...]复制对象的一种好方法是提供 copy构造器 copy factory 。复制构造函数只是一个带有单个参数的构造函数,该参数的类型是包含该构造函数的类:

  public Yum(Yum yum ); 

复制工厂是静态工厂的类似物复制构造函数:

 公共静态Yum newInstance(Yum yum); 




相关问题








替代:可克隆 2.0



如果您真的坚持要拥有一个类似于 Cloneable 的功能且不会损坏,您可以编写类似以下内容(为增加爵士乐而生):

 公共类DupableExample {

接口Dupable< T> {
T dup();
}
静态类Sheep实现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());

//不需要强制转换
Sheep dolly2 = new Sheep(null).dup();
}
}

输出应该是这样的(在ideone.com上看到):

  DupableExample $ Sheep @ {一些十六进制代码} 
DupableExample $ Sheep @ {在所有可能的情况下都是不同的十六进制代码}

所以现在给定任何 Dupable< T> ,您可以调用 T dup()

这只是一个概念验证:在实际实现中,您的副本构造函数/副本工厂/无论哪种复制机制实际上都会实现复制逻辑,并且 Dupable< T> 将是 public 顶层界面


its easier to explain in code so here

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

what can i use instead of the Object.clone() method in this example?

----------------------- extra info ------------------------------

I have added extra info but it seems to have gone in the middle of all the answers, so here it is again so it can be read.

Hi all these are all really helpful on topic of cloning or copying, which i now need to think about. but they dont help with the initial question. maybe more info from me will help you understand what im after.

I am overriding the clone for each of my objects and adding all the other clone and copy methods needed to completely clone the object, this includes adding a custom method to copy a bufferedimage. 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; 
    } 
}

but i have one variable in my class that is an Object but because it hold various other objects of different types, each of my types will have a clone method, but short of checking if its each of my types and then calling clone() on my type, which would be very long as i have many types, i cannot see how to copy or clone the object easily. is there a way os should i just write a static method like this?

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
}

???

解决方案

You seem to have realized that Cloneable in Java is broken.

Here are some quotes from an interview with Josh Bloch, author of Effective Java 2nd Edition:

If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken. There are a few design flaws, the biggest of which is that the Cloneable interface does not have a clone method. And that means it simply doesn't work: making something Cloneable doesn't say anything about what you can do with it. Instead, it says something about what it can do internally. It says that if by calling super.clone repeatedly it ends up calling Object's clone method, this method will return a field copy of the original.

But it doesn't say anything about what you can do with an object that implements the Cloneable interface, which means that you can't do a polymorphic clone operation.

Here are some quotes from the book, Item 11: Override clone judiciously:

[...] you are better off providing alternative means of object copying, or simply not providing the capability.

[...] A fine approach to object copying is to provide copy constructor or copy factory. A copy constructor is simply a constructor that takes a single argument whose type is the class containing the constructor:

public Yum(Yum yum);

A copy factory is the static factory analog of a copy constructor:

public static Yum newInstance(Yum yum);

Related questions


Alternative: Cloneable 2.0

If you really insist on having a Cloneable-like functionality that isn't broken, you can write something like this (generified for extra jazz):

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

The output should be something like this (as seen on ideone.com):

DupableExample$Sheep@{some hexadecimal code}
DupableExample$Sheep@{a different hexadecimal code, in all likelyhood}

So now given any Dupable<T>, you can invoke T dup() on it to get what you expect is a duplicate copy.

This is just a proof-of-concept: in actual implementation, your copy constructor/copy factory/whatever copy mechanism will actually have the copying logic implemented, and Dupable<T> would be a public top-level interface.

这篇关于如何克隆您不知道类型的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆