これはJava Concurrency in Practiceからの一文です
共有読み取り専用オブジェクトには、不変オブジェクトと事実上不変オブジェクトが含まれます。
不変オブジェクトと実質的に不変オブジェクトの違いは何ですか?
これはJava Concurrency in Practiceからの一文です
共有読み取り専用オブジェクトには、不変オブジェクトと事実上不変オブジェクトが含まれます。
不変オブジェクトと実質的に不変オブジェクトの違いは何ですか?
拡張可能ではなく、すべてのフィールドfinal
とそれ自体が不変であるクラスのインスタンスは、不変です。
メソッドの詳細のためにフィールドを変更できないクラスのインスタンスは、事実上不変です。例えば:
final class C {
final boolean canChange;
private int x;
C(boolean canChange) { this.canChange = canChange; }
public void setX(int newX) {
if (canChange) {
this.x = newX;
} else {
throw new IllegalStateException();
}
}
}
のいくつかのインスタンスC
は事実上不変であり、いくつかのインスタンスはそうではありません。
もう 1 つの例は、長さ 0 の配列です。変更可能な要素がないため、それらを含むクラスが証明可能な不変ではない場合でも、それらは事実上不変です。
Joe-E はベリファイアを使用して、一部のクラスが不変インスタンスのみを許可することを証明します。マーカー インターフェイスでマークされたImmutable
ものはすべてチェックされ、(エスケープしないためString
実質的に不変) のような特定のクラスは不変として除外されます。char[]
Joe-E: Java のセキュリティ指向のサブセットは言う
Joe-E ライブラリによって定義された Immutable インターフェースは、言語によって特別に扱われます。Joe-E ベリファイアは、このインターフェースを実装するすべてのオブジェクトが (深く) 不変であることをチェックし、これが自動的に変更できない場合はコンパイル時エラーを発生させます。検証済み。
これは、少しグーグルしてこの記事を見つけることからの私の理解です。効果的に不変なオブジェクトは、変更可能なフィールドを含むオブジェクトですが、それらのフィールドへの参照を提供しないため、それらのフィールドを変更することはできません。たとえば、 を含むクラスを作成するとしますArrayList
。 ArrayList
s は可変ですが、クラスが常に ArrayList のコピーを返し、クラス内の他のすべてが不変である場合、クラスは事実上不変になります。クラスのインスタンスの状態を変更する方法はありません。
ブログ投稿では、実質的に不変のクラスの例としてこれを示しています。
import java.awt.*;
public class Line {
private final Point start;
private final Point end;
public Line(final Point start, final Point end) {
this.start = new Point(start);
this.end = new Point(end);
}
public void draw() {
//...
}
public Point getStart() {
return new Point(start);
}
public Point getEnd() {
return new Point(end);
}
}
Point
オブジェクトは変更可能ですが、このクラスはそのPoint インスタンスへの直接参照を誰にも与えないため、問題ありません。代わりに、同じ値を持つ新しいインスタンスを返します。そうすれば、誰もLine
クラスの状態を変更できなくなります。これにより、Line
クラスは事実上不変になります。
では、これは真の不変クラスとどう違うのでしょうか? 真に不変のクラスには、不変のフィールドもあります。Line
本当に不変だったと想像してみましょう。Point
そのためには、それが不変であると想像する必要もあります。これらの仮定を行うと、getStart()
メソッドは次のように記述できた可能性があります。
public Point getStart() {
return start;
}
この答えを見てください:
実質的に不変と不変 実質的に不変と不変の違いは、最初のケースでは、オブジェクトを安全な方法で公開する必要があることです。必要のない真に不変のオブジェクト用。したがって、真に不変なオブジェクトは公開しやすいため好まれます。前述の理由は、非同期公開を好む理由を示しています。