私は、Javaのバージョンが7より小さいと、Joda TimeオブジェクトはJavaの組み込み関数よりも信頼性が高いと読んでいます。 1つの理由は、Jodaオブジェクトは不変であるという理由が挙げられます。なぜこれは有益なのでしょうか? Joda DateTimeオブジェクトの年、時間、およびタイムゾーンを変更したい場合は、3つのコピーを作成する必要があります。なぜJodaオブジェクトは不変ですか?
答えて
ジョーダDateTimeオブジェクトの年、時間、およびタイムゾーンを変更する場合は、3つのコピーを作成する必要があります。
はい、または、新しいオブジェクトを作成し、古いオブジェクトから好きなすべてのフィールドを使用することもできます。
これは徹底的に良いことです。変化しないオブジェクトに頼っていたいと思うからです。 Instant
は不変であるので、大丈夫です
private static final Instant EARLIEST_ALLOWED_ARTICLE = ...;
private Instant creationTimestamp;
public Article(Instant creationTimestamp, ...) {
if (creationTimestamp.isBefore(EARLIEST_ALLOWED_ARTICLE)) {
throw new IllegalArgumetnException(...);
}
this.creationTimestamp = creationTimestamp;
...
}
:この擬似コードを考えてみましょう。変更可能な場合は、その時点で防御的なコピーを作成していない限り、コンストラクタの検証は意味がありません。
私の経験では、参照を渡して、値が実際に既存のオブジェクトを変更したいと思う以上に変化しないようにするため、不変性によりバグが少なくなります。どんな妥当性検査も役に立たず、コピーが少なくなります。
基本的には、コードを受け入れるか保存するか、または他のコードに戻ることはできません。 あなたのコードだけがあなたのオブジェクトの状態を変えることができるとき、時間が経つにつれて起こることを簡単に解決することができます。 インターフェース(例えばReadableInstant
)にあなただけのプログラムは、あなたがそれらの保証を取得しない場合 - それは可変と不変型の両方を持っているので、
ジョダ時間は実際には多少失敗します。それで、Noda Timeでは、すべてのタイプを真に不変にしました。
お困りですか?String
は変更可能ですか?そうでない場合、2つのシナリオの間に本当の違いがあるかどうかを考えてみてください。
これは優れた点です。しかし、日付は本当に何か特別なものです、 "プリミティブ"(数字と文字列)は不変ですか?なぜあなたは*すべてのクラスを変更可能にしてはいけないのか、すべての*セッター*が*値を変更する前にコピーを作成していないのかという疑問が浮かび上がってきます。あなたが書いたすべてのセッターに 'クローン'または 'コピー'と書くのは本当に意味がありません。これは基本的な問題を暗示します。 – caw
@caw:そうです、日付は本当に*特別なものだと言います。変更可能な型を持つことは間違いありませんが、実現可能な場合は一般的には不変型を優先します。しかし、低レベルの "プリミティブ"型がすべて可変であれば、*可変性または不変性の* choice *は実装するのがはるかに難しくなります...不変のクラスは常に*すべてをクローンする必要があります*。 Urgh。 –
ありがとう!日付と他の一般的なオブジェクト(例えば、コレクション、 'カレンダー'、ビジネスロジックからのオブジェクト)の間に大きな違いはまだありません。とにかく、後で変更することができない(したがってパブリックセッターを持たないかもしれない)オブジェクトの間に*実質的な違いがあり、コンストラクタ/セッターで受け取ったデータをクローンするだけですJoshua Blochが "Effective Java"で推奨しているものです)と、*変更しようとするオブジェクトはすべてのセッターで自分自身をコピーする必要があります。 – caw
最も単純な答えは、オブジェクトを作成すると、はに変更できないことがわかります。つまり、予期しない方法でデータが変更されるような状況に陥ることはありません(おそらく、コードの他の部分や別のスレッドではおそらく)。
これにより、オブジェクトの動作がより予測可能で信頼性が高くなります。
多くの理由があるかもしれませんが、1つの良い点はハッシングです。不変オブジェクトは、ハッシュコードと "等価"セマンティクスが変更されないため、ハッシュデータ構造(HashSet、HashMapsのキーなど)で使用できます。可変オブジェクトはハッシュコードや等価性を変更する可能性があるため、可変オブジェクトはハッシュには適していません。
Jodaの日付を不変にすることで、データ構造のハッシュ処理に使用できるようになりました。
私はそれがこのによるものだと仮定します:
あなたはjava.util.Dateオブジェクトを持っている想像し、それを複数のクラスで使用されています。私は1つのクラスで開発をしています。それから私は将来を予測する必要があると判断しますが、新しいDateオブジェクトを作成するのではなく、私がすでに持っているもの、つまり特定の時点を表すと考えるものを取り上げ、それに3時間を追加します。さて、あなたのコードは実行時に深刻な問題に遭遇するかもしれません。これは、あなたがその状態を変更することはできないので、不変のオブジェクトを使って避けることができます。他の誰かのためにそれを混乱させることはできません。
残念ながら、final
が使用されていないため、DateTimeの実装は不変ではありません[1]。
https://github.com/JodaOrg/joda-time/blob/master/src/main/java/org/joda/time/DateTime.java
[1]用語 "不変" は一般に "スレッドセーフ不変" を意味すると理解されます。
- 1. なぜintは不変ですか?
- 2. なぜJoda Intervalは匹敵しなかったのですか?
- 3. Joda LocaldateをJoda DateTimeに変換する方法ですか?
- 4. なぜlinq-2-sqlは不要な不要なオブジェクトを作成しますか?
- 5. jQueryオブジェクトは不変ですか?
- 6. なぜ `object`クラスのインスタンスはPythonでは不変ですか?
- 7. なぜ番号はJavascriptで不変ですか?
- 8. なぜ配列は不変ですが、リストは共変型ですか?
- 9. なぜ反応小道具は不変ですか?
- 10. なぜApacheのベンチマークの結果は不変ですか?
- 11. Jodaが生の型Comparableを拡張するのはなぜですか?
- 12. joda DateTimeZoneのgetOffset()メソッドが「インスタント」を必要とするのはなぜですか?
- 13. 世代別GCで不変オブジェクトがより効率的になるのはなぜですか?
- 14. OrientDBオブジェクトAPIのJoda DateTime
- 15. なぜ/ ENTRYリンカオプションは不要ですか?
- 16. なぜ「jQuery.parseJSON」は不要ですか?
- 17. なぜJoda DateTimeをカレンダーに変換して戻ってcenturyOfEraフィールドを変更するだけですか?
- 18. 可変オブジェクトにダブルポインタが必要なのはなぜですか?
- 19. 不変オブジェクトと実効不変オブジェクトの違いは?
- 20. Joda Time .isAfter()不正な結果を生成します
- 21. Joda TimeのPeriod.getMillisが不正確な数値を返します
- 22. .NET不変オブジェクト
- 23. C#で不変クラスが封印されないのはなぜですか?
- 24. なぜ "不明なクラス"ですか?
- 25. イベントのオブジェクトにプロパティが不足しているのはなぜですか?
- 26. Java、不可能なオブジェクトを浮かべる.....なぜ?
- 27. Setの要素として不変オブジェクトを使用するのはなぜ好ましいですか?
- 28. なぜ結果オブジェクトを変更できないのですか
- 29. 不変のオブジェクトをコピーする点は何ですか? ObjCで
- 30. なぜ "変更可能なメソッドを不変オブジェクトに送信する"例外が発生しましたか?
逆に、DateTimeオブジェクトが不変でない場合、Javaに 'const'がないと仮定すると、サードパーティのAPIにパラメータとして渡すたびに、そのオブジェクトを複製すると仮定されます。 –