不変の二つのことを意味することができますことを検討する価値がある:
A)を渡す場合は、この値は、それが変異することはできませんsomwhereこと。
B)「」と
それが安全に、マルチスレッド環境で使用することができる広告A)スレッドセーフだけで不変ではなく、あるクラスがあり、彼らはセッター/ゲッターとしてまで使用することが良いですHashMapのキーである - これらはミューテータを持たず、すべてのフィールドはプライベートだが、すべてのフィールドがfinalでもvolatileでもない。
ad B)不変でスレッドセーフなクラスがあります。これらはミューテータがなく、すべてのフィールドがprivateとfinalまたはvolatileです。
スレッドセーフであるクラスは、ドキュメントや名前でも記述されることがよくありますが、もちろんいくつかのクラスは不変でもスレッドセーフでもかまいませんが、厳密に文書化されているわけではありません。たとえば、String
クラスは「定数」と記述されていますが、スレッドの安全性に関する情報はありません。「文字列オブジェクトは不変なので共有できます」という謎の文が1つしかありません。他のスレッドと共有します。私たちは一般的なクラスのプロパティを知っているだけですが、これらのプロパティを明確に文書化する必要があることに同意します。実生活で不幸にも彼らはそうではありません。したがって、クラスが不変であるかどうかを知る唯一の方法は、ドキュメンテーションをチェックし、十分な情報がない場合は、実装をチェックし、将来クラスを変更可能にするかどうかを作者に尋ねます。このトピックは、「Java Concurrency in Practice」の中で考察されており、著者は、何かが@ThreadSafe
および/または@Immutable
であることを示すために2つの注釈を使用することを推奨しますが、残念ながらこれはまだ一般的な方法ではありません。
まあ、これらのクラスにはどのようなミューテータもありません... 'String.concat()'とは違って、新しい連結されたものを返すのではなく 'String'を修正すると思います。 – Kayaman
"開発者は実装を読むことが期待されます"いいえ、あなたはそうすることは決してありません。しかし、あなたは*ドキュメンテーション*からそれを推論することができます(それは 'final'です、setterはありません)。 –
@AndyTurnerあなたが不変であることに依存します。不変性は、「最終的な」フィールドなどの実装の詳細に依存するスレッド安全性のコンテキストでよく議論されます。 – shmosel