复制构造函数应该有多深

时间:2013-08-09 22:00:03

标签: java constructor deep-copy

  1. 是否应该为传递给构造函数的可变对象的对象引用设置防御副本?

  2. 如果是,那么我应该如何“深入”制作副本。在下面的示例中,我应该在所涉及的所有类的副本构造函数中进行深层复制吗?

  3. 例如:

    class Graph {
        AdjacencyList;
        public Graph(Graph graph) {
          this.list = graph.list;   // shallow copy
          OR
          this.list = ArrayCopy(graph.list);  // deep copy
        }
    }
    
    class DFS implements GraphAlgo {
       Graph g
       DFS(Graph g) {
         this.g = g;   // shallow copy
         OR
         this.g = new Graph(graph)  // deep copy
       }
    
       DFS(Algo algo) {
         this.g = algo.g;  // shallow copy
         OR
         this.g = new Graph(algo.g);  // deep copy
       }
    
    }
    
    class Algo {
       GraphAlgo galgo
    
       Algo (GraphAlgo dfsalgo) {
          galgo  = dfsalgo  // shallow copy
          OR
          galgo = new DFSAlgo(dfsalgo); // deep copy
       }
    }
    

    3 ..如果有些课忘记实施深拷贝怎么办?这是否意味着我永远不会有一个安全的深度复制对象?有什么方法可以防止这种情况吗?

2 个答案:

答案 0 :(得分:5)

你应该防守吗?
只有你需要。

你要去多深?
尽可能深入。

声音陈腐?那么,这类问题的基本答案是“尽可能少地提供所需的功能”。

答案 1 :(得分:2)

一般情况下:除非您不信任主叫代码,否则不要制作防御性副本。

执行:记录界面,并说如果这会导致问题,则不允许他们更改通过您的任何内容。

有时:提供两个构造函数。一个使用该对象。一个人复制。然后让调用者在需要时调用复制者。在调用构造函数后,调用者可能会丢弃对该对象的任何引用。在这种情况下,不需要复制。

Algo (GraphAlgo dfsalgo, boolean doCopy) {
    if (doCopy) {
        galgo = new DFSAlgo(dfsalgo); // deep copy
    } else {
        galgo  = dfsalgo  // shallow copy
    }
}

如果您信任调用代码:忽略此问题。期望它在调用你的代码之前复制它不会丢弃的东西(从它自己的角度来看)。

偏执狂并不意味着他们不能帮助你。但这并不意味着他们也是。