2017-08-24 6 views
3

Integer,Double,Booleanなどのタイプラッパーは不変であることはよく知られています。しかし、公式のAPIドキュメントでこれを見つけることができませんでした(例:https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html)。私もソースコードファイルを見て、ではないこれはコメントに記載されているを見つける。 (Stringのソースコード内のコメントは、他の一方で、その不変性に言及しません。)このため、Javaラッパークラスの不変性に関する文書

は、次のとおりです。
- それは別の場所で文書化されます(そうであれば、どこ?)が、
は - この事実はあまりにもあります"よく知られている"、または
- 開発者はラッパーの実装を読み、ラッパーが不変であるかどうかを判断する必要がありますか?

+0

まあ、これらのクラスにはどのようなミューテータもありません... 'String.concat()'とは違って、新しい連結されたものを返すのではなく 'String'を修正すると思います。 – Kayaman

+5

"開発者は実装を読むことが期待されます"いいえ、あなたはそうすることは決してありません。しかし、あなたは*ドキュメンテーション*からそれを推論することができます(それは 'final'です、setterはありません)。 –

+1

@AndyTurnerあなたが不変であることに依存します。不変性は、「最終的な」フィールドなどの実装の詳細に依存するスレッド安全性のコンテキストでよく議論されます。 – shmosel

答えて

0

ボックス化されたラッパーは、実質的に がラップするリテラルタイプと構文的に互換性があるため、「不変」です。例えばbooleanは不変である:ほとんどのプログラミング言語で

boolean x = false; 
x.flip(); // not implemented 

ネイティブ型は不変です。したがって、ラッパー契約により、

Boolean x = false; 
x.mutate(/* ??? */); 

も定義されていません。

1

不変の二つのことを意味することができますことを検討する価値がある:

A)を渡す場合は、この値は、それが変異することはできませんsomwhereこと。

B)「」と

それが安全に、マルチスレッド環境で使用することができる広告A)スレッドセーフだけで不変ではなく、あるクラスがあり、彼らはセッター/ゲッターとしてまで使用することが良いですHashMapのキーである - これらはミューテータを持たず、すべてのフィールドはプライベートだが、すべてのフィールドがfinalでもvolatileでもない。

ad B)不変でスレッドセーフなクラスがあります。これらはミューテータがなく、すべてのフィールドがprivateとfinalまたはvolatileです。

スレッドセーフであるクラスは、ドキュメントや名前でも記述されることがよくありますが、もちろんいくつかのクラスは不変でもスレッドセーフでもかまいませんが、厳密に文書化されているわけではありません。たとえば、Stringクラスは「定数」と記述されていますが、スレッドの安全性に関する情報はありません。「文字列オブジェクトは不変なので共有できます」という謎の文が1つしかありません。他のスレッドと共有します。私たちは一般的なクラスのプロパティを知っているだけですが、これらのプロパティを明確に文書化する必要があることに同意します。実生活で不幸にも彼らはそうではありません。したがって、クラスが不変であるかどうかを知る唯一の方法は、ドキュメンテーションをチェックし、十分な情報がない場合は、実装をチェックし、将来クラスを変更可能にするかどうかを作者に尋ねます。このトピックは、「Java Concurrency in Practice」の中で考察されており、著者は、何かが@ThreadSafeおよび/または@Immutableであることを示すために2つの注釈を使用することを推奨しますが、残念ながらこれはまだ一般的な方法ではありません。

関連する問題