Java のすべての最終クラスは不変です。String と Integer はどちらも最終クラスであり、どちらも不変です。
8 に答える
いいえ、final はクラスを拡張できないことを意味します。可変性については何も言いません。例えば:
final class MutInt {
public int modifyMe;
}
いいえ - 最終クラスは、それから継承できないことを意味します。可変性とは何の関係もありません。次のクラスは final ですが変更可能です。
public final class FinalMutable {
int value;
public void setValue(int v) { value=v; }
public int getValue() { return value; }
}
不変性のキーワードはなく、デザイン パターンのようなものです。
編集:
これは、クラスを不変にするキーワードがないことを意味します。クラスを不変にするには、内部を final または private にして保護する必要があります。
紛らわしいのはこれです: final キーワードは、クラスで使用される場合と、フィールド/変数で使用される場合とで異なる意味を持ちます。前者は「このクラスは拡張できない」という意味です。2 つ目は、「この変数 (または参照) は変更できない」という意味です。
前に他の人が言ったfinal
ように、Java でクラスを不変にすることはありませんが、不変性戦略の一部を果たします。不変性を得るには、一般的なガイドラインに従う必要があります。
- クラスをオーバーライドできないようにする - クラスを作成する
final
か、静的ファクトリを使用してコンストラクタを非公開にします - フィールド
private
を作り、final
- メソッドへの後続の呼び出しと組み合わせて引数のないコンストラクターを使用する代わりに、呼び出し元に単一のステップでオブジェクトを完全に構築するように強制し
setXXX
ます (つまり、Java Beans 規則を回避します)。 setXXX
メソッドだけでなく、状態を変更できるメソッドを提供しないでください。- クラスに変更可能なオブジェクト フィールドがある場合は、クラスとその呼び出し元の間で渡されるときに防御的にコピーする必要があります。
他の応答に加えて、 のコードをjava.lang.String
見ると、 field: が含まれていることがわかります。hash
これは変更可能hashCode()
で、実際には が初めて呼び出されたときに計算および保存されます。
ただし、クラスは依然として不変です。hash
フィールドに直接アクセスしたり、クラス外で変更したりすることはできません。
また、JDK 内の一般的なアプローチは、変更を許可せずにオブジェクトの内部状態を公開するために使用できる不変ラッパーの実装であることに気付くかもしれません。例えば
private final List<String> values;
public List<? get String> getValues() {
return Collections.unmodifiableList(values);
}
プライベート フィールドは、サブクラスのオーバーライドされたメソッドによってアクセスできません...したがって、サブクラス メソッドがスーパー クラスのプライベート フィールドを変更する方法はありません...では、不変クラスを final にすることの用途は何ですか?
final キーワードは、他のクラスがそれを継承するのを防ぎます。final キーワードはそれを不変にするわけではありませんが、インスタンス クラス メンバーを非公開にして最終的なものにし、getter を使用し、setter を使用しないなどの条件があります。