复制构造函数和防御性复制

时间:2013-02-22 09:31:16

标签: java defensive-programming

什么是 复制构造函数

有人可以分享一个有助于理解 防御性复制原则 的小例子吗?

5 个答案:

答案 0 :(得分:13)

这是一个很好的例子:

class Point {
  final int x;
  final int y;

  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }

  Point(Point p) {
    this(p.x, p.y);
  }

}

请注意构造函数Point(Point p)如何获取Point并复制它 - 这是copy constructor

这是defensive副本,因为原始Point可以通过复制它来保护其免受更改。

现在:

// A simple point.
Point p1 = new Point(3,42);
// A new point at the same place as p1 but a completely different object.
Point p2 = new Point(p1);

请注意,这不一定是创建对象的正确方式。但是,它是一种良好方式来创建对象,以确保您不会偶然对同一对象进行两次引用。显然,如果这是你想要实现的目标,这只是一件好事。

答案 1 :(得分:6)

复制构造函数经常在C ++中看到,部分隐藏的,自动调用的操作需要它们。

脑海中浮现出

java java.awt.PointRectangle;也是非常古老,可变的物体。

通过使用不可变对象,例如StringBigDecimal,只需指定对象引用即可。事实上,由于Java之后的Java早期阶段,仍然有一个 String

中的愚蠢复制构造函数
public class Recipe {
    List<Ingredient> ingredients;

    public Recipe() {
        ingredients = new ArrayList<Ingredient>();
    }

    /** Copy constructor */
    public Recipe(Recipe other) {
        // Not sharing: ingredients = other.ingredients;
        ingredients = new ArrayList<Ingredient>();
        ingredients.addAll(other.ingredients);
    }

    public List<Ingredient> getIngredients() {
        // Defensive copy, so others cannot change this instance.
        return new ArrayList<Ingredient>(ingredients);
        // Often could do:
        // return Collections.immutableList(ingredients);
    }
}

答案 2 :(得分:1)

当您需要克隆对象时,可以使用java中的复制构造函数

class Copy {
   int a;
   int b;
  public Copy(Copy c1) {
    a=c1.a;
    b=c1.b;
  }
}

在java中给出复制c2=c1;只需创建对原始对象的引用而不是副本,因此您需要手动复制对象值。

见:

答案 3 :(得分:1)

复制构造函数用于使用现有对象的值创建新对象。
一个可能的用例是保护原始对象不被修改,同时可以使用复制的对象进行处理。

public class Person  
{  
   private String name;  
   private int age;  
   private int height;  


/** 
 * Copy constructor which creates a Person object identical to p.  
 */  
   public person(Person p)  
   {  
      person = p.person;  
      age = p.age;  
      height = p.height;  
   }  
.
.
. 
}

与防御性副本相关here是一个很好的阅读

答案 4 :(得分:0)

这是通过传递旧对象,复制其值来创建新对象的地方。

Color copiedColor = new Color(oldColor);

而不是:

Color copiedColor = new Color(oldColor.getRed(),
                              oldColor.getGreen(), oldColor.getBlue());