2016-04-13 2 views
2

はのは、次のスニペットJavaコンストラクタで参照型を常にクローンするのは良い方法ですか?

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が、すべてでは変更されませんでした。

したがって、コンストラクタで常に参照型を常に複製することをお勧めしますか?型が複製可能でない場合はどうなりますか?

+6

いいえ、参照型を常に*クローン化するのは良い方法ではありません。もしあなたが不変な参照型(例えば 'String')を持っていれば、それは完全に不必要であり、パフォーマンスのために悪いです。 – Jesper

+0

はい、ありません。あなたがクラスの一つのインスタンスを複数の他のクラスを通して共有したいと想像してみましょう。このインスタンスで1つの値を変更した場合は、他の参照の値も変更する必要があります。 – SomeJavaGuy

+6

20年以内にプロダクションコードで 'clone()'を使ったことがありません。 – EJP

答えて

1

いいえ、Open-Closed Principleに違反するため、参照型を複製することは必ずしも良い習慣ではありません。 Bertrand MeyerによるOCPは、ソフトウェアエンティティが拡張のために開かれるべきであるが、修正のために閉じることをと述べている。

この記事を読むarticle(Do not provide a public copy constructor)

1

配列を扱う場合、は、ほとんどの場合には、です。その理由は、配列の要素を直接変更することによって、パラメータ配列を作成したインスタンスの外部で変更することができるからです。配列が変更されないように保護する唯一の方法は、そのクローン/コピーを作成することです。クローンを行うことは、値渡しで参照渡しをオーバーライドすること以外には何もありません。どの方法を実行するかは、実装の要件によって異なります。

*)参照(つまりデコレータまたはラッパー)で配列を渡す場合があります。この場合は、まったく複製しないでください。

関連する問題