clone()vs copy constructor vs factory方法?

clone()vs copy constructor vs factory方法?

我在Java上实现了克隆()的快速谷歌,发现:http//www.javapractices.com/topic/TopicAction.do?Id = 71

它有以下评论:

复制构造函数和静态工厂方法提供了克隆的替代方法,并且更容易实现。

我想做的就是做一份深刻的副本。实现clone()似乎很有意义,但这篇谷歌排名很高的文章让我有点害怕。

以下是我注意到的问题:

复制构造函数不适用于泛型。

这是一些无法编译的伪代码。

public class MyClass<T>{
   ..
   public void copyData(T data){
       T copy=new T(data);//This isn't going to work.    
   }
   ..}

示例1:在泛型类中使用复制构造函数。

工厂方法没有标准名称。

拥有可重用代码的接口非常好。

public class MyClass<T>{
    ..
    public void copyData(T data){
        T copy=data.clone();//Throws an exception if the input was not cloneable
    }
    ..}

示例2:在泛型类中使用clone()。

我注意到克隆不是静态方法,但是不是仍然需要制作所有受保护字段的深层副本吗?在实现clone()时,在非可克隆子类中抛出异常的额外工作对我来说似乎微不足道。

我错过了什么吗?任何见解将不胜感激。


至尊宝的传说
浏览 620回答 3
3回答

泛舟湖上清波郎朗

基本上,克隆被打破了。什么都不会轻易与泛型一起使用。如果你有这样的东西(缩短以获得重点):public&nbsp;class&nbsp;SomeClass<T&nbsp;extends&nbsp;Copyable>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;T&nbsp;copy(T&nbsp;object)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(T)&nbsp;object.copy(); &nbsp;&nbsp;&nbsp;&nbsp;}}interface&nbsp;Copyable&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;Copyable&nbsp;copy();}然后使用编译器警告您可以完成工作。因为泛型在运行时被擦除,所以执行复制的东西会在其中生成编译器警告生成强制转换。在这种情况下,这是不可避免的。。在某些情况下这是可以避免的(谢谢,kb304),但不是全部。考虑必须支持子类或实现接口的未知类的情况(例如,您正在迭代不一定生成相同类的可复制副本集合)。

侃侃无极

还有Builder模式。有关详细信息,请参阅Effective Java我不明白你的评价。在复制构造函数中,您完全了解类型,为什么需要使用泛型?public&nbsp;class&nbsp;C&nbsp;{ &nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;value; &nbsp;&nbsp;&nbsp;public&nbsp;C()&nbsp;{&nbsp;} &nbsp;&nbsp;&nbsp;public&nbsp;C(C&nbsp;other)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;other.value; &nbsp;&nbsp;&nbsp;}}最近这里也有类似的问题。public&nbsp;class&nbsp;G<T>&nbsp;{ &nbsp;&nbsp;&nbsp;public&nbsp;T&nbsp;value; &nbsp;&nbsp;&nbsp;public&nbsp;G()&nbsp;{&nbsp;} &nbsp;&nbsp;&nbsp;public&nbsp;G(G<?&nbsp;extends&nbsp;T>&nbsp;other)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;other.value; &nbsp;&nbsp;&nbsp;}}一个可运行的样本:public&nbsp;class&nbsp;GenTest&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;interface&nbsp;Copyable<T>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;copy(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;<T&nbsp;extends&nbsp;Copyable<T>>&nbsp;T&nbsp;copy(T&nbsp;object)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;object.copy(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;class&nbsp;G<T>&nbsp;implements&nbsp;Copyable<G<T>>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;T&nbsp;value; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;G()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;G(G<?&nbsp;extends&nbsp;T>&nbsp;other)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;=&nbsp;other.value; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;G<T>&nbsp;copy()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;G<T>(this); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;G<Integer>&nbsp;g&nbsp;=&nbsp;new&nbsp;G<Integer>(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.value&nbsp;=&nbsp;1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;G<Integer>&nbsp;f&nbsp;=&nbsp;g.copy(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.value&nbsp;=&nbsp;2; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;G<Integer>&nbsp;h&nbsp;=&nbsp;copy(g); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.value&nbsp;=&nbsp;3; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.printf("f:&nbsp;%s%n",&nbsp;f.value); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.printf("g:&nbsp;%s%n",&nbsp;g.value); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.printf("h:&nbsp;%s%n",&nbsp;h.value); &nbsp;&nbsp;&nbsp;&nbsp;}}

千巷猫影

Java没有与C ++相同的复制构造函数。你可以有一个构造函数,它接受一个与参数类型相同的对象,但很少有类支持这个。(少于支持克隆的数量)对于通用克隆,我有一个辅助方法,它创建一个类的新实例,并使用反射复制原始字段(浅拷贝)(实际上像反射但更快)对于深层复制,一种简单的方法是序列化对象并对其进行反序列化。顺便说一句:我的建议是使用不可变对象,然后你就不需要克隆它们了。;)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java