Почему объекты Joda неизменны?

Я читал, что в версии Java менее 7 объекты Joda Time более надежны, чем встроенные модули Java. Одна из приведенных причин заключается в том, что объекты Joda неизменны. Почему это выгодно? Если я хочу изменить год, час и часовой пояс объекта Joda DateTime, мне нужно сделать три копии!

5 ответов

Решение

Если я хочу изменить год, час и часовой пояс объекта Joda DateTime, мне нужно сделать три копии!

Да, в самом деле. Или вы можете создать один новый объект, используя все поля, которые вам нравятся, из старого объекта, конечно.

Это очень хорошая вещь - потому что это означает, что когда вы хотите, чтобы объект не менялся, это не так. Рассмотрим этот псевдокод:

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) тогда вы не получите эти гарантии. Вот почему в Noda Time я сделал все типы по-настоящему неизменными.

Из интереса, вы бы хотели String быть изменчивым? Если нет, попробуйте подумать, есть ли реальные различия между этими двумя сценариями.

Самый простой ответ - когда вы создаете объект, вы знаете, что он не может измениться. Это означает, что вы не столкнетесь с ситуацией, когда ваши данные изменятся неожиданным образом (возможно, в других частях кода или в других потоках).

Это делает поведение объекта более предсказуемым и надежным.

Я бы предположил, что это связано с этим:

Представьте, что у вас есть объект java.util.Date, который используется в нескольких классах. Я занимаюсь разработкой в ​​одном классе, а вы - в другом. Затем я решаю, что мне нужно предсказать будущее, но вместо создания нового объекта Date я беру тот, который у меня уже есть, тот, который, по вашему мнению, представляет определенный момент времени, и добавляю к нему три часа. Теперь ваш код может столкнуться с серьезными проблемами во время выполнения. Этого можно избежать, используя неизменный объект, потому что вы не можете изменить его состояние, вы не можете испортить его кому-либо еще.

К сожалению, реализация DateTime не является неизменной [1], так как нет final используется.

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

[1] Термин "неизменяемый" обычно понимается как "потокобезопасный неизменяемый".

Может быть много причин, но одна хорошая относится к хешированию. Неизменяемые объекты могут использоваться в хэшировании структур данных (например, HashSet, ключи в HashMaps и т. Д.), Потому что их хэш-код и семантика "равенства" не изменятся. Изменяемые объекты не подходят для хеширования, поскольку мутации могут изменить свой хэш-код или равенство.

Делая даты Joda неизменяемыми, они теперь могут использоваться в хэшировании структур данных.

Другие вопросы по тегам