2011-11-19 164 views
11

克隆对象我需要实现'可复制的'接口。因为在这里我的课是一个jar文件(我的意思是API)。所以我不能编辑课程。我听说所有类都扩展了基类对象类,而这个对象类实现了可复制的接口。这是否意味着我们可以直接克隆对象而不用实现接口。如果是这样在我的日食我没有得到任何选项来克隆对象。 是否有任何其他方式来克隆对象而不实现可复制接口。请解释。克隆对象克隆与实现可复制的接口

+1

为什么你觉得你必须这样做?你最好告诉我们你想要解决的总体问题,而不是你认为解决这个问题可能需要的编程步骤。换句话说,你可能会遇到一些错误的事情。 –

+0

每个评论的答案,我认为OP想要一个复制构造函数。 – msandiford

+0

嗨气垫船。在这里我清楚地解释我的问题。我有一个名为XYZ的类,我有一个返回这个XYZ类的对象的方法。私人XYZ getObject(){return obj; }我通过调用这个方法创建了一个对象。 XYZ obj1 = getObject();问题来了。实际上我想要再次调用方法时创建一个对象。我不能在这里编辑XYZ类。我想做XYZ obj2 =(XYZ)obj1.clone();但我无法在我的XYZ类上实现'可复制'界面。那么还有什么其他方式可以为这个班级创建一个更多的对象。 – ran

回答

5

Java Object类未实现接口Cloneable。它确实有clone()方法。但是这种方法是protected,如果在不实现接口Cloneable的对象上调用,则会抛出CloneNotSupportedException。所以,如果你不能修改你想克隆的类,那么你的运气不好,将不得不寻找另一种方法来复制实例。

但应该注意的是,Java中的克隆系统充满了漏洞并且通常不再使用。请从2002年与Josh Bloch一起查看interview,解释一些问题。

+0

是否有任何其他方式克隆的对象,而不实施可复制的界面......感谢您的回复 – ran

+0

“但应该注意的是,Java中的克隆系统充满了漏洞,通常不再使用。” - 你可以添加声明的参考吗? –

+0

您可以使用构造函数创建新实例,并将所需状态复制到其中。这种可行性实际上取决于您想要复制的对象类别。 – orien

0

试图对未实现Cloneable的类调用clone方法抛出CloneNotSupported异常,并且没有Object类不实现Cloneable。

这里是从Object类

CloneNotSupportedException if the object's class does not 
*    support the <code>Cloneable</code> interface. Subclasses 
*    that override the <code>clone</code> method can also 
*    throw this exception to indicate that an instance cannot 
*    be cloned. 

而且对象#clone方法是受保护的,所以你需要实现类的clone方法并予以公布,以便它可以接触到的克隆方法的Javadoc创建你的类的对象的类然后可以调用克隆。一个很好的例子是克隆的方式实现的ArrayList

ArrayList中像下面 公共类的ArrayList扩展AbstractList的 实现列表,了RandomAccess,Cloneable的实现可复制,java.io.Serializable接口

,然后实现clone方法:

/** 
* Returns a shallow copy of this <tt>ArrayList</tt> instance. (The 
* elements themselves are not copied.) 
* 
* @return a clone of this <tt>ArrayList</tt> instance 
*/ 
public Object clone() { 
try { 
    ArrayList<E> v = (ArrayList<E>) super.clone(); 
    v.elementData = Arrays.copyOf(elementData, size); 
    v.modCount = 0; 
    return v; 
} catch (CloneNotSupportedException e) { 
    // this shouldn't happen, since we are Cloneable 
    throw new InternalError(); 
} 
} 
+0

嗨gaurav,正如我已经提到,我不能在我的课上实现可复制的接口。但我想用现有对象的不同名称创建重复对象。有没有其他办法可以做到这一点。 – ran

+0

如果您问是否可以克隆不能编辑的课程对象。答案是不。从理论上讲,您可以使用反射来访问类的变量,从而能够获取并复制其状态,但是如果您允许访问类的私有成员,则依赖于安全管理器。即使在这种情况下,也可能无法进行深度复制。 –

+0

您应该在这种情况下使用复制构造函数,而不是'clone()'。谷歌的第一个链接是这样的:http://www.javapractices.com/topic/TopicAction.do?Id=12 – msandiford

0

Object类中的clone()方法受到保护,这意味着所有类都将使用受保护的访问修饰符继承它,因此,如果尝试在不克隆它的情况下在该类之外访问它,那么您不会看到它,同时它也会抛出CloneNotSupportedException如果您尝试在不实现Cloneable接口的情况下调用它。

如果您正在寻找创建克隆行为的方法,您需要在您的类中编写一个新方法,然后创建一个所有字段的副本,其基本类似于创建一个新的副本对象的现有状态。

public class TestCloneable { 
private String name = null; 

/** 
* @param name the name to set 
*/ 
public void setName(String name) { 
    this.name = name; 
} 

/** 
* @return the name 
*/ 
public String getName() { 
    return name; 
} 


public TestCloneable createCopy(){ 
    TestCloneable testCloneable = new TestCloneable(); 
    testCloneable.setName(this.getName()); 
    return testCloneable; 
} 

}

5

它通常是最好的做法,以避免克隆()反正,因为它是很难正确地做(http://www.javapractices.com/topic/TopicAction.do?Id=71)。也许有问题的类有一个拷贝构造函数?

或者如果它实现Serializable或外部化,可以通过深其写入字节流和回读的

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
ObjectOutputStream oos = new ObjectOutputStream(baos); 
oos.writeObject(this); 
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 
ObjectInputStream ois = new ObjectInputStream(bais); 
Object deepCopy = ois.readObject(); 

(从http://www.jguru.com/faq/view.jsp?EID=20435)复制它。这很简单,但并不漂亮......我通常会认为这是最后的手段。

+0

嗨凯尔。感谢您的回复。但我完全不明白这一点。你能告诉我在我的情况下,我该怎么做。 – ran

+0

复制构造函数如下所示:public XYZ(XYZ toCopy)。而不是调用o.clone(),你可以调用新的XYZ(o)。可序列化的部分意味着如果可以将XYZ写入流中,那么可以将它写入流(实际上只是内存中的一个字节数组),然后从该流中读回,从而有效地创建副本。 – kylewm

+0

复制构造函数的限制是您需要在代码创作时知道类的类型。如果我传入“XYZ”的子类,'public XYZ(toCopy)'将不起作用。 –

0

不强制实施可复制的界面,使一个对象的克隆。 您可以在要克隆其对象的类中编写自己的克隆方法。

+1

这不提供问题的答案。一旦你有足够的[声誉](https://stackoverflow.com/help/whats-reputation),你将可以[对任何帖子发表评论](https://stackoverflow.com/help/privileges/comment);相反,[提供不需要提问者澄清的答案](https://meta.stackexchange。COM /问题/ 214173 /为什么-DO-I-需要50声誉对评论 - 什么 - 可以-I-DO-代替)。 - [来自评论](/ review/low-quality-posts/18867158) –