15

Javaのバージョンが7未満の場合、JodaTimeオブジェクトはJavaの組み込みオブジェクトよりも信頼性が高いことを読みました。引用された理由の1つは、Jodaオブジェクトが不変であるということです。なぜこれが有益なのですか?Joda DateTimeオブジェクトの年、時間、およびタイムゾーンを変更する場合は、3つのコピーを作成する必要があります。

4

5 に答える 5

19

Joda DateTimeオブジェクトの年、時間、およびタイムゾーンを変更する場合は、3つのコピーを作成する必要があります。

はい、確かに。または、もちろん、古いオブジェクトから好きなすべてのフィールドを使用して、1つの新しいオブジェクトを作成することもできます。

これは完全に良いことです。つまり、オブジェクトが変更されないことに依存したい場合、変更されないことを意味します。この擬似コードを考えてみましょう。

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;
    ...
}

Instantは不変なので、それで問題ありません。変更可能である場合、その時点で防御コピーを作成しない限り、コンストラクターでの検証は無意味になります。

私の経験では、参照を渡し、既存のオブジェクトに実際に変更を加えたい以上に値が変更されないことを知りたいので、不変性によってバグが少なくなります(可変オブジェクトでは、コピーを取るのを忘れることができます。その場合、検証は役に立たなくなり、作成されるコピーが少なくなります。

基本的に、受け入れて保存したり、他のコードに戻ったりするすべてのコピーを作成することなく、コードについてローカルで推論することができます。コードだけがオブジェクトの状態を変更できる場合、時間の経過とともに何が起こるかを理解する方がはるかに簡単です。

Joda Timeは、可変型と不変型の両方を備えているため、実際には多少失敗します。インターフェイス(たとえばReadableInstant)にプログラムするだけでは、これらの保証は得られません。そのため、野田時間では、すべてのタイプを真に不変にしました。

興味深いことに、変更可能になりたいStringですか?そうでない場合は、2つのシナリオの間に実際の違いがあるかどうかを考えてみてください。

于 2012-09-20T18:30:22.530 に答える
3

最も簡単な答えは、オブジェクトを作成すると、それを変更できないことがわかっているということです。これは、データが予期しない方法で(おそらくコードの他の部分や別のスレッドで)変更される状況に遭遇しないことを意味します。

これにより、オブジェクトの動作がより予測可能で信頼性の高いものになります。

于 2012-09-20T18:30:03.947 に答える
1

多くの理由があるかもしれませんが、1つの良い理由はハッシュに関するものです。不変オブジェクトは、ハッシュコードと「等価」セマンティクスが変更されないため、データ構造のハッシュ(HashSet、HashMapsのキーなど)で使用できます。ミュータブルはハッシュコードまたは等価性を変更する可能性があるため、ミュータブルオブジェクトはハッシュには適していません。

Jodaの日付を不変にすることで、データ構造のハッシュに使用できるようになりました。

于 2012-09-20T18:32:09.990 に答える
1

私はそれがこれによるものだと思います:

複数のクラスで使用されるjava.util.Dateオブジェクトがあるとします。私は一方のクラスで開発を行っており、もう一方のクラスではあなたです。次に、将来を予測する必要があると判断しますが、新しいDateオブジェクトを作成する代わりに、既存のオブジェクト、つまり特定の時点を表すと思われるオブジェクトを取得し、それに3時間を追加します。これで、実行時にコードで重大な問題が発生する可能性があります。不変オブジェクトを使用すると、状態を変更したり、他の人に混乱させたりすることができないため、これをすべて回避できます。

于 2012-09-20T18:34:05.133 に答える
1

残念ながら、DateTimeの実装は、nofinalが使用されているため、不変ではありません[1]。

https://github.com/JodaOrg/joda-time/blob/master/src/main/java/org/joda/time/DateTime.java

[1]「不変」という用語は、一般に「スレッドセーフな不変」を意味すると理解されています。

于 2012-09-20T18:43:12.473 に答える