什么是 复制构造函数 ?
有人可以分享一个有助于理解 防御性复制原则 的小例子吗?
答案 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.Point
和Rectangle
;也是非常古老,可变的物体。
通过使用不可变对象,例如String
或BigDecimal
,只需指定对象引用即可。事实上,由于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());