什么是好习惯?复制构造函数或防御性复制方法

时间:2013-08-22 06:25:04

标签: java copy-constructor defensive-programming

我有一个Graph类,我需要该图的副本。我将修改图形对象的内部(例如:删除边缘等)。我有2种方法来实现图表。

  1. 复制构造函数
  2. 一种名为'getGraph(){return new Graph(this)}'的方法。这个方法getGraph可以做一个防御性的副本。
  3. 根据我的理解,复制构造函数的唯一优点是copy-at-will。这意味着如果我不想修改图形对象,则不需要'getGraph'来做防御性复制。

    现在回到我的问题。

    1. 使用复制构造函数更好还是使用返回自身对象副本的函数更好?
    2. 为什么?

4 个答案:

答案 0 :(得分:2)

在不知道您需要什么的情况下,最好将复制定义为方法,因为潜在的子类可以覆盖方法。如果Graph有一个子类,例如为每个节点添加颜色,则在Graph中调用复制构造函数,您只能复制纯图,从而丢失子类中的附加信息和功能。另一方面,复制图形的方法可以在子类中重写。

您可能会发现Object.clone方法很有用,但请记住其要求(必须实施Cloneble并覆盖clone方法)和限制(仅限浅层复制)不妨从头开始编写你的复制方法。

答案 1 :(得分:1)

据我了解你的问题

在复制构造函数中,您可以执行类似

的操作
Graph copy = new Graph(objectToBeCloned);

并且在getGraph()中你会做

Graph copy = objectToBeCloned.getGraph();

我建议您使用Graph类实现Cloneable接口并覆盖clone()方法,以获得所需的深层副本。

答案 2 :(得分:1)

我想说一个复制构造函数在Graph对象中的getGraph方法上有更多的语义。所以在两者之间我更喜欢复制构造函数。

请不要考虑使用克隆,它已被设计破坏,请阅读Object Identity以获取有关它的更多信息。 您还有一些替代方案,在此处表达:clone vs copy constructor

答案 3 :(得分:1)

我不确定你是否还在寻找这个问题的答案,但由于这个问题未被标记为已回答,我将回答这个问题。

由于您选择使用复制构造函数

Graph clonedGraph = new Graph(originalGraph);

或防御性副本

Graph clonedGraph = originalGraph.getGraph();

我可以说你知道Object.clone()的缺点,我建议你采用防御性复制策略,因为它是多态的,并且还为你提供了反转控制或依赖注入的优势。

如果您有一个Graph子类(将来可能需要),并且尝试将该子类的对象分配给Graph的引用,然后尝试复制构造函数策略将失败为它创建副本。您可以在Java Cloning - Why Copy Constructors Are Not Sufficient

上阅读更多内容