Я учился, Java является ссылкой на объект передачи значением, и для создания локальной копии объекта, я могу или сделать клон () или конструктор копии. Я также посмотрел на глубокую/мелкую копию, а также несколько сообщений на stackoverflow.
Теперь я смотрю на пример:
List<String> list = new ArrayList<String>();
String one = "one"
list.add(one);
Немного статей I упоминаний только для чтения, что ArrayList реализует cloneable, но действительно не заявляет, как сделать локальную копию "списка", если тип является Списком не ArrayList, который не делает cloneable реализаций.
Я могу назвать клон (), если "список" является типом ArrayList.
ArrayList<String> list = new ArrayList<String();
list.clone();
Но если тип является Списком, я не могу.
Я должен просто использовать конструктора копии как ниже для создания локальной копии? Что лучший способ состоит в том, чтобы сделать копией "списка"?
List<String> tmpList = new ArrayList<String>(list);
Передача списка в конструктор, вероятно, лучший способ. Сам вызов конструктора будет за кулисами использовать System.arraycopy. Таким образом, он эффективно отделит локальную копию от списка, переданного через конструктор.
Используйте конструктор копирования всегда, когда это возможно. clone()
устарел и не должен использоваться (как и реализовываться) в новом коде.
Если вы расширяете класс, который реализует
Cloneable
, у вас нет выбора, кроме как реализовать хорошо работающий методclone
. В противном случае, вам лучше предоставить альтернативный способ копирования объектов или просто не предоставлять такую возможность. [...] Отличным подходом к копированию объектов является предоставление копирующего конструктора или копирующей фабрики. [...]Учитывая все проблемы, связанные с
Cloneable
, можно с уверенностью сказать, что другие интерфейсы не должны расширять его, и что классы, предназначенные для наследования (пункт 17) не должны его реализовывать. Из-за его многочисленных недостатков некоторые опытные программисты просто предпочитают никогда не переопределять методclone
и никогда не не вызывать его, за исключением, возможно, копирования массивов.
Из Effective Java 2nd Edition, пункт 11.