始终在Java构造函数中克隆引用类型是一种好习惯吗?

时间:2016-04-13 12:57:38

标签: java constructor

让我们考虑以下代码段

public class A {
    private String[] a; 
    public A(String[] a) { this.a = a; }
    @Override public void foo() { System.out.println(a[0]); }
}

以及以下用法:

String[] t = {"bar", "foo"};
A x = new A(t);
x.foo(); // prints "bar"
t[0] = "foo";
x.foo(); // prints "foo"

虽然x根本没有修改过。

因此,总是克隆构造函数中的引用类型是一种好的做法吗?如果类型不可复制怎么办?

2 个答案:

答案 0 :(得分:1)

在处理数组时,在大多数情况下是一种很好的做法*。原因是,通过直接修改数组的元素,可以在创建的实例之外修改参数数组。因此,保护​​阵列不被改变的唯一方法是创建它的克隆/副本。做克隆只不过是用pass-by-value覆盖pass-by-reference。哪种方式取决于实施的要求。

*)在某些情况下,您可能希望通过引用传递数组(即装饰器或包装器),在这种情况下,您根本不应克隆它。

答案 1 :(得分:1)

克隆引用类型并不总是一个好习惯,因为它会违反开放原则。 Bertrand Meyer撰写的OCP声明软件实体应该开放以进行扩展,但是因修改而关闭

阅读此article(Do not provide a public copy constructor)