2014-02-07 3 views
0

У меня есть список объектов компании. Я пытаюсь клонировать этот список:Сделайте глубокую копию с клоном

public static List<Company> cloneList(List<Company> list) { 
    List<Company> clone = new ArrayList<Company>(list.size()); 
    for(Company item: list) clone.add(item.clone()); 
    return clone; 
} 

Однако мой компилятор говорит:

Multiple markers at this line 
    - The method add(Company) in the type List<Company> is not applicable for the arguments 
    (Object) 

Почему это не возможно сделать глубокую копию с clone()?

ответ

1

Метод clone() определяется на корневом классе Object (см here). Таким образом, он возвращает объект, если вы не изменили свой тип возвращаемого значения на конкретный класс при переопределении, вы должны применить его к соответствующему типу, например. :

clone.add((Company) item.clone()); 

или определить clone() с ковариантном типом возвращаемого в своем классе, как:

public class Company implements Cloneable { 
    // stuff ... 

    public Company clone() throws CloneNotSupportedException { /* do clone */ } 
}  

Обратите внимание, что вы имеют переопределить метод клонирования, как это определено с видимостью защищаемого.

По соглашению классы, реализующие этот интерфейс, должны переопределять Object.clone (который защищен) общедоступным методом. Дополнительную информацию об переопределении этого метода см. В Object.clone(). [source]

Также см. this вопрос для других вариантов.

+0

Thx для вашего ответа! Однако мой компилятор теперь возвращает мне: 'Метод clone() из типа Object не отображается' – user2051347

+0

Thx для вашего ответа! Что бы вы поместили в '/ * do clone * /'? – user2051347

+1

Код, который создает копию объекта с использованием super.clone, а затем заменяет все ссылки на изменяемое состояние, которое может не использоваться совместно с копией этого состояния. Это также относится к состоянию, которое транзитивно достижимо. Внедрение клона может быстро усложниться. Я бы посоветовал вам не использовать clone(). Вместо этого используйте конструктор копирования или фабрику копирования. – Pyranja

1

Проблема в том, что item.clone() возвращает объект.
Вы можете придумать здесь. Так что попробуйте изменить его к этому:

clone.add((Company)item.clone());

Кроме того, переопределения клон в классе компании.
Самый простой способ сделать это будет этот.

public Object clone(){ 
    return super.clone(); 
} 

Но вы можете придумать нестандартную реализацию.

+0

Thx для вашего ответа! Теперь мой компилятор возвращает мне: 'Метод clone() из типа Object не отображается' – user2051347

+1

Отвечено обновлено. –

-1

clone() реализуется Object и возвращает объект. Переопределите clone() в своем классе или отправьте свой результат в компанию.

clone.add((Company) item.clone());

1

Вы вводите в заблуждение cloning и genericity.

В вашем случае вам нужно просто бросить свой клон, как так:

clone.add((Company)item.clone()); 

Также убедитесь, что вы глубоко клонировать объекты по overrriding метод Object#clone (см Object.clone():

В противном случае, это метод создает новый экземпляр класса этого объекта и инициализирует все его поля точно содержимым соответствующих полей этого объекта, как если бы оно было назначено, содержимое полей само не клонировано.Таким образом, этот метод выполняет «мелкую копию» этого объекта, а не операцию «глубокой копии».

Смежные вопросы