Java 什么是良好实践?复制构造函数或防御复制方法

Java 什么是良好实践?复制构造函数或防御复制方法,java,copy-constructor,defensive-programming,Java,Copy Constructor,Defensive Programming,我有一个类图,我需要一个该图的副本。我将修改graph对象的内部结构(例如:删除边等)。我有两种实现图形的方法 复制构造函数 一个名为“getGraph(){returnnewgraph(this)}”的方法。此方法getGraph可以执行防御复制 根据我的理解,复制构造函数的唯一优点是可以随意复制。这意味着如果我不想修改graph对象,就不需要“getGraph”进行防御复制 现在回到我的问题 使用复制构造函数更好还是使用返回自身对象副本的函数更好 为什么? 据我所知,你的问题 在复制构造函数

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

  • 复制构造函数
  • 一个名为“getGraph(){returnnewgraph(this)}”的方法。此方法getGraph可以执行防御复制
  • 根据我的理解,复制构造函数的唯一优点是可以随意复制。这意味着如果我不想修改graph对象,就不需要“getGraph”进行防御复制

    现在回到我的问题

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

  • 据我所知,你的问题

    在复制构造函数中,您可以执行以下操作

    Graph copy = new Graph(objectToBeCloned);
    
    在getGraph()中,您可以

    Graph copy = objectToBeCloned.getGraph();
    

    我建议让你的Graph类实现
    Cloneable
    接口并重写
    clone()
    方法,以获得你需要的深度副本。

    据我所知,你的问题

    在复制构造函数中,您可以执行以下操作

    Graph copy = new Graph(objectToBeCloned);
    
    在getGraph()中,您可以

    Graph copy = objectToBeCloned.getGraph();
    

    我建议让您的Graph类实现
    Cloneable
    接口并重写
    clone()
    方法以获得所需的深度副本。

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


    您可能会发现该方法很有用,但请记住它的要求(必须实现并覆盖
    克隆
    方法)和限制(仅制作浅拷贝),您最好从头开始编写复制方法。

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


    您可能会发现该方法很有用,但请记住它的要求(必须实现并覆盖
    克隆
    方法)和限制(仅制作浅拷贝),您最好从头开始编写复制方法。

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

    请不要考虑使用克隆,它被设计打破了,阅读更多关于它的信息。
    您还有一些备选方案,在这里表示:

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

    请不要考虑使用克隆,它被设计打破了,阅读更多关于它的信息。
    您也有一些备选方案,在这里表示:

    我不确定您是否仍在寻找此问题的答案,但由于该问题未标记为已回答,我将回答它

    因为你选择了复制构造函数

    Graph clonedGraph = new Graph(originalGraph);
    
    还是防御性副本

    Graph clonedGraph = originalGraph.getGraph();
    
    我可以告诉您,您已经意识到
    Object.clone()
    的缺点,我建议您使用防御性复制策略,因为它是多态的,并且还提供了反转控制或依赖项注入的优势


    如果您有一个子类
    Graph
    (将来可能需要),并尝试将该子类的对象分配给
    Graph
    的引用,然后尝试为其创建副本,则复制构造函数策略将失败。您可以在

    上阅读更多内容。我不确定您是否仍在寻找此问题的答案,但由于该问题未标记为已回答,因此我将回答它

    因为你选择了复制构造函数

    Graph clonedGraph = new Graph(originalGraph);
    
    还是防御性副本

    Graph clonedGraph = originalGraph.getGraph();
    
    我可以告诉您,您已经意识到
    Object.clone()
    的缺点,我建议您使用防御性复制策略,因为它是多态的,并且还提供了反转控制或依赖项注入的优势


    如果您有一个子类
    Graph
    (将来可能需要),并尝试将该子类的对象分配给
    Graph
    的引用,然后尝试为其创建副本,则复制构造函数策略将失败。您可以阅读更多关于
    Graph
    类中为什么有
    getGraph
    方法的内容?您是否在
    Graph
    类本身中引用了
    Graph
    实例?是。这是一种返回。什么是拷贝构造函数,什么是防御拷贝?我想你需要深度复制。这听起来很奇怪。你能显示你当前的代码吗?我知道我需要一个深度复制,但它是通过一个复制构造函数还是通过一个显式方法进行深度复制?为什么在
    Graph
    类中有
    getGraph
    方法?您是否在
    Graph
    类本身中引用了
    Graph
    实例?是。这是一种返回。什么是拷贝构造函数,什么是防御拷贝?我想你需要深度复制。这听起来很奇怪。你能显示你当前的代码吗?详细解释一下为什么你需要这个?我知道我需要一个深度复制,但它是通过一个复制构造函数还是通过一个显式方法来进行深度复制?谢谢你的帮助,但我的问题是以下哪一个选项