Ява.утиль.Дата клонирования или копирования, чтобы не предоставлять внутреннюю ссылку


рекомендуется не раскрывать внутренние ссылки на объект (сущность). Так что если объект имеет поле типа java.util.Date тогда, например, геттер для этого поля должен возвращать не исходную дату, а ее копию.

но для java.утиль.Дата существует два распространенных способа создания этой копии:

  • клон: (Date) originalDate.clone()
  • скопировать через конструктор new Date(originalDate.getTime())

мой вопрос в том, какой путь лучше, и почему?

3 61

3 ответа:

если это определенно просто Date, Это не имеет никакого значения в любом случае.

если фактический объект может быть подкласс на Date (например,java.sql.Date), то я надеюсь, что clone() сохранит дополнительную информацию (в том числе о том, какой это класс), тогда как вызов конструктора не будет.

кстати, если вы использовали Джода Времени у вас не было бы этой проблемы, так как есть много неизменяемых типов для использования. Это также много лучше по API :)

читать Эффективная Java. Предпочтительным способом создания копий является использование подхода конструктора копий.

Билл Веннерс: в своей книге вы рекомендуете использовать конструктор копирования вместо реализации клонирования и написания клона. Не могли бы вы подробнее об этом?

Джош блох: Если вы читали статью о клонировании в моей книге, особенно если Вы читаете между строк, вы будете знать, что я думаю клон глубоко сломлен. Есть несколько недостатков дизайна, самый большой из них это означает, что клонируемый интерфейс не имеет метода клонирования. И это означает, что он просто не работает: делает что-то клонируемым ничего не говорит о том, что вы можете с ним сделать. Вместо этого он говорит: что-то о том, что он может сделать внутренне. Он говорит, что если по телефону супер.клонировать повторно он заканчивает вызов метода клонирования объекта, это метод вернет копию поля оригинала.

Если вы кодируете защищенно, вам понадобится конструктор копирования. Смотрите этот отрывок из эффективной Java:

Обратите также внимание, что мы не использовали метод клонирования даты для создания защитных копий. Поскольку дата не является окончательной, метод clone не гарантирует возврат объекта, класс которого является java.утиль.Дата; он может возвращать экземпляр ненадежного подкласса, специально предназначенного для злонамеренного озорства. Такой подкласс мог бы, например, записать a ссылка на каждый экземпляр в частном статическом списке в момент его создания и разрешить злоумышленнику доступ к этому списку. Это даст злоумышленнику свободу действий во всех инстанциях. Чтобы предотвратить такого рода атаку, не используйте метод clone для создания защитной копии параметра, тип которого поддается классификации ненадежными сторонами.