0

不変とは、インスタンス化された後に状態が変わらないオブジェクトであることを意味することを理解しています。しかし、このコード行では、配列値が宣言されているときに Final が表示されません。このクラスは不変ですか?どなたか調べ方を教えていただけないでしょうか。ありがとう

public class A {
private double[] values;
public double[] getValues(){
return values;
 }
}
4

4 に答える 4

1

他の人が書いたように、このオブジェクトはその状態で可変であると見なされます。不変なのは、それが保持する配列を交換できないことです。ただし、配列の内容は変更できます (getValues()[0] = 10;)。

これを不変オブジェクトに変換するには、配列の代わりに List を使用する必要があります。リストを使用すると、コレクションのメソッドunmodifiableListを使用して、指定されたリストを、安全に外部に公開できるバージョンに変換できます。getValues() の呼び出し元が変更不可能なリストで add または remove を使用すると、 UnsupportedOpertionException が発生し、オブジェクトの保存が変更されないようにします。

配列に固執する必要がある場合は、配列のコピー (System.arraycopy) またはクローン (clone()) を提供する必要があります。

通常、オブジェクトのプロパティ (スーパークラスから継承されたプロパティを含む) を変更できない場合、オブジェクトは不変であると見なされます。通常、これにはプロパティ値も含まれますが、これはあいまいな定義です。

たとえば、ドキュメント ファイルを指す File インスタンスを保持するクラスがあり、この File インスタンスを変更できない場合、クラスは不変 (提供される情報は変更されない) と見なされますが、それが指すドキュメントは変更可能であり、毎回変わりました。したがって、実際にはぼやけた線です(例では、配列を変更することはできませんが、配列の内容を変更することはできません)。

于 2013-10-17T17:35:24.403 に答える
0

はい、貼り付けられたコードには最終的なキーワードが関連付けられておらず、不変の動作はありません。

さて、Java での不変クラスの作成に関連するいくつかの重要なガイドラインを提示したいと思います。

1.) クラスをオーバーライドできないようにする - クラスを final にするか、静的ファクトリを使用してコンストラクタを非公開にします

2.) setXXX メソッドへの後続の呼び出しと組み合わせて引数のないコンストラクターを使用する代わりに、フィールドを非公開にし、呼び出し元に 1 つのステップでオブジェクトを完全に構築するよう強制します (つまり、Java Beans 規則を回避します)。

3.) オブジェクトの状態を変更できるメソッドを提供しないでください。setXXX メソッドだけでなく、状態を変更できるメソッドも提供しないでください。

4.) クラスに変更可能なオブジェクト フィールドがある場合は、それらがクラスとその呼び出し元の間を通過するときに防御的にコピーする必要があります。

于 2013-10-17T17:09:56.620 に答える
0
A a = new A();
a.getValues()[0] = 1.2;

これは、値が空でない限り機能します。ただし、値を新しい配列に再割り当てすることはできません。つまりa.getValues() = new double[5];、機能しません。

値を変更することはできますが、再割り当てすることはできないため、クラスは不変ではありません。

于 2013-10-17T17:17:05.103 に答える