Вы часто читаете о неизменяемых объектах, требующих, чтобы конечные поля были неизменными в Java. Действительно ли это так, или просто достаточно, чтобы не иметь никакой общественной изменчивости и фактически не мутировать государство?Должны ли поля быть явно окончательными, чтобы иметь «правильный» неизменяемый объект?
Например, если у вас есть неизменяемый объект, построенный по шаблону строителя, вы можете сделать это, если строитель присваивает отдельные поля по мере их сборки или имеет застройщик, удерживающий сами поля, и в конечном итоге возвращает неизменяемый объект передавая значения его (частному) конструктору.
Наличие окончательного поля дает очевидное преимущество предотвращения ошибок реализации (например, позволяет коду сохранять ссылку на строитель и «строить» объект несколько раз, в то же время мутируя существующий объект), но имея хранилище Builder его данные внутри объекта по мере его создания выглядят как DRYer.
Вопрос: Предположим, что Builder не пропустил объект раньше и перестает модифицировать объект после его создания (например, установив его ссылку на объект как нуль), на самом деле что-то получилось (например, улучшенная безопасность потоков) в «неизменности» объекта, если поля объекта были сделаны окончательными?
Если я не ошибаюсь * final * также может помочь предотвратить «атаки отражения», когда программист-изгоев будет использовать отражение для доступа к полям вашего класса и изменения их содержимого. Был знаменитый пример, полностью извращающий класс * String * и показывающий, что во многих случаях * String * действительно может быть изменен (если не из-за неточности btw, а из-за того, что после базового * char [] * был доступен, если была «игра окончена», потому что вы не можете заставить неизменность по содержанию массива ... Но это не моя точка зрения: я хочу сказать, что отражение может помочь сделать действительно неприятные вещи). – TacticalCoder
@user, перед лицом такого отражения вы не можете установить неизменность. Тем не менее, диспетчер безопасности работает над тем, чтобы сделать сторонний код таким же жизнеспособным. – Yishai
wait ... Если у меня есть * final * класс, имеющий уникальный * final int *, вы можете изменить его с помощью отражения? Моя точка зрения заключалась именно в том, что * без * использования * final * вы не можете предотвратить атаки отражения (если у вас нет * Security Manager * на месте, но это почти никогда не бывает, поэтому я написал *) во многих случаях может быть изменено "* ...). Однако я не уверен, что вы можете использовать отражение, чтобы изменить * final int * ... Если вы не можете, то мой комментарий довольно по теме с вашим вопросом:) (Я сделал +1 ваш вопрос вчера кстати:) – TacticalCoder