Clone()vs Copy构造函数-在java中建议使用
java中的克隆方法与复制构造函数。哪一个是正确的解决方案。在哪里使用每个案例?克隆已损坏,因此不要使用它 对象类的克隆方法 这是一种神奇的方法 任何纯Java方法都做不到的事情 do:它生成一个相同的 它的目标。它已经出现在 自 Java测试版发布日 编译器*;它就像所有古代的东西一样 魔法,需要适当的 咒语,以防止咒语 出人意料地适得其反 首选复制对象的方法Clone()vs Copy构造函数-在java中建议使用,java,clone,copy-constructor,Java,Clone,Copy Constructor,java中的克隆方法与复制构造函数。哪一个是正确的解决方案。在哪里使用每个案例?克隆已损坏,因此不要使用它 对象类的克隆方法 这是一种神奇的方法 任何纯Java方法都做不到的事情 do:它生成一个相同的 它的目标。它已经出现在 自 Java测试版发布日 编译器*;它就像所有古代的东西一样 魔法,需要适当的 咒语,以防止咒语 出人意料地适得其反 首选复制对象的方法 Foo copyFoo (Foo foo){ Foo f = new Foo(); //for all properties
Foo copyFoo (Foo foo){
Foo f = new Foo();
//for all properties in FOo
f.set(foo.get());
return f;
}
阅读更多
请记住,
clone()
不是现成的。您必须实现Cloneable
并重写public
中的clone()
方法
有几个备选方案更可取(因为clone()
方法有很多设计问题,如其他答案中所述),复制构造函数需要手动操作:
- 创建一个浅克隆,就像由
创建的一样。(本课程来自)Object.clone()
- 创建深度克隆。(即,克隆整个属性图,不仅克隆第一级)(from),而且所有类都必须实现
Serializable
- 提供深度克隆,无需实现
Serializable
// Need to clone person, which is type Person
Person clone = new Person(person);
如果person
可以是person
的子类(或者如果person
是一个接口),则这不起作用。这就是克隆的全部意义,它可以在运行时动态克隆正确的类型(假设克隆正确实现)
或
现在,person
可以是任何类型的person
,前提是clone
的实现是正确的。clone()的设计有几个错误(请参阅),因此最好避免它
Person clone = (Person)person.clone();
从,第11项:明智地覆盖克隆
考虑到与Cloneable相关的所有问题,可以肯定地说
其他接口不应该扩展它,而类
为继承而设计(第17项)不应实现它。因为
它有很多缺点,一些专家程序员干脆选择不做
重写clone方法,并且永远不要调用它,除非
复制数组。如果为继承设计类,请注意
如果选择不提供性能良好的受保护克隆方法,则
子类不可能实现Cloneable
本书还描述了复制构造函数相对于可克隆/克隆的许多优势
- 他们不依赖于有风险的语言外物体创造机制
- 他们不要求不可强制执行地遵守记录很少的约定
- 它们与final字段的正确使用没有冲突
- 它们不会抛出不必要的已检查异常
- 他们不需要石膏
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
List original=//一些列表
列表副本=新阵列列表(原件);
巨大的悲哀:可克隆/克隆和构造函数都不是很好的解决方案:我不想知道实现类!!!(例如,我有一个地图,我想使用相同的隐藏MumbleMap实现复制它)如果支持的话,我只想复制一个。但是,遗憾的是,Cloneable上没有clone方法,因此您无法安全地键入cast来调用clone()
无论最好的“复制对象”库是什么,Oracle都应该让它成为下一个Java版本的标准组件(除非它已经隐藏在某个地方)
当然,如果库的更多部分(如集合)是不可变的,那么这个“复制”任务就会消失。但是,接下来我们将开始使用“类不变量”而不是verdammt“bean”模式来设计Java程序(创建一个破碎的对象,并进行变异,直到性能达到[足够好]。不惜一切代价避免
clone
并采用您自己的复制解决方案。复制构造函数比object.clone()更好因为他们不强迫我们实现任何接口或抛出任何异常,但如果需要,我们肯定可以做到,不需要任何强制转换,不要求我们依赖未知的对象创建机制,不要求父类遵循任何约定或实现任何东西,允许我们修改最终字段,允许我们完全控制对象的创建,我们可以在其中编写初始化逻辑。阅读更多,嗯,克隆没有被破坏。你认为这是为什么?如果这是因为如果不重写它,它就不能工作,那么,这就是它的契约。@Bozho,阅读有效的Java第二版,Bloch解释得很好。除了克隆数组(),Doug Lea甚至不再使用clone()
。我真的不明白为什么克隆不能更简单。这是一种选择吗?或者,在一般情况下,这背后确实存在着严重的问题?@polygene我也没有使用clone()
,这就是我建议使用beanutils的原因。但我的观点是,可以使用clone()
,尽管这是“明智的”。在简单的情况下,它工作得相当好。因此,让我们结束汽车比喻-这就像说,俄罗斯汽车的工作。我承认我还没有读过有效的Java,但我要说的是,Cloneable作为一个接口有其优势。也就是说,您可以将泛型类和函数的参数限制为只接受实现可克隆的类,然后只调用clone()。没有它,我不相信有一个(好的)方法来执行t
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);