клонирование объектов без реализации клонируемого интерфейса - PullRequest
14 голосов
/ 19 ноября 2011

для клонирования объекта мне нужно реализовать «клонируемый» интерфейс.потому что здесь мой класс - это jar-файл (я имею в виду API).поэтому я не могу редактировать класс.Я слышал, что все классы расширяют базовый класс объектов, и этот класс объектов реализует клонируемый интерфейс.Означает ли это, что мы можем напрямую клонировать объект без реализации интерфейса?Если так, то в моем затмении у меня нет возможности клонировать объект. существует ли другой способ клонирования объекта без реализации клонируемого интерфейса .пожалуйста, объясни.

Ответы [ 7 ]

8 голосов
/ 19 ноября 2011

Как правило, в любом случае лучше избегать clone (), потому что это трудно сделать правильно (http://www.javapractices.com/topic/TopicAction.do?Id=71). Возможно, у рассматриваемого класса есть конструктор копирования?

В качестве альтернативы, если он реализует Serializable или Externalizable, вы можете глубоко скопировать его, записав его в поток байтов и считав его обратно в

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object deepCopy = ois.readObject();

(из http://www.jguru.com/faq/view.jsp?EID=20435). Это быстро и просто, но не красиво ... Я бы вообще посчитал это последним средством.

7 голосов
/ 19 ноября 2011

Класс Java Object не реализует интерфейс Cloneable.Однако у него есть метод clone().Но этот метод равен protected и будет вызывать CloneNotSupportedException, если вызывается для объекта, который не реализует интерфейс Cloneable.Поэтому, если вы не можете изменить класс, который хотите клонировать, вам не повезло, и вам нужно будет найти другой способ скопировать экземпляр.

Следует отметить, однако, что система клонирования в Java полна дыри вообще больше не используется.Проверьте это интервью с Джошем Блохом от 2002 года, объясняющее некоторые из проблем.

1 голос
/ 08 апреля 2018

Используя Reflection API, вы можете достичь этого

1 голос
/ 28 марта 2013

Это API, который клонирует объект без реализации клонируемого интерфейса.

Попробуйте это

https://github.com/kostaskougios/cloning

Также вы можете найти более подробную информацию о клонировании объектов здесь

http://javatechniques.com/blog/faster-deep-copies-of-java-objects/

0 голосов
/ 19 февраля 2018

Необязательно реализовывать клонируемый интерфейс для создания клона объекта. Вы можете написать свой собственный метод клонирования в классе, объект которого вы хотите клонировать.

0 голосов
/ 19 ноября 2011

Метод clone () в классе Object защищен, что означает, что все классы будут наследовать его с модификатором защищенного доступа, следовательно, если вы попытаетесь получить к нему доступ вне этого класса, не клонируя его, вы его не увидите, а также вы получите исключение CloneNotSupportedException, если вы пытаетесь вызвать его без реализации интерфейса Cloneable.

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

public class TestCloneable {
private String name = null;

/**
 * @param name the name to set
 */
public void setName(String name) {
    this.name = name;
}

/**
 * @return the name
 */
public String getName() {
    return name;
}


public TestCloneable createCopy(){
    TestCloneable testCloneable = new TestCloneable();
    testCloneable.setName(this.getName());
    return testCloneable;
}

}

0 голосов
/ 19 ноября 2011

Попытка вызвать метод clone для класса, который не реализует Cloneable, создает исключение CloneNotSupported, и ни один класс Object не реализует Cloneable.

вот код Javadoc из метода клона класса Object

CloneNotSupportedException  if the object's class does not
 *               support the <code>Cloneable</code> interface. Subclasses
 *               that override the <code>clone</code> method can also
 *               throw this exception to indicate that an instance cannot
 *               be cloned.

Кроме того, метод Object # clone защищен, поэтому вам необходимо реализовать метод clone в вашем классе и сделать его общедоступным, чтобы он мог быть доступен для классов, создающих объекты вашего класса, которые затем могут вызывать clone. Хорошим примером является способ реализации клона в ArrayList

ArrayList реализует клонируемый, как показано ниже открытый класс ArrayList расширяет AbstractList реализует List, RandomAccess, Cloneable, java.io.Serializable

и затем реализует метод клонирования:

/**
 * Returns a shallow copy of this <tt>ArrayList</tt> instance.  (The
 * elements themselves are not copied.)
 *
 * @return a clone of this <tt>ArrayList</tt> instance
 */
public Object clone() {
try {
    ArrayList<E> v = (ArrayList<E>) super.clone();
    v.elementData = Arrays.copyOf(elementData, size);
    v.modCount = 0;
    return v;
} catch (CloneNotSupportedException e) {
    // this shouldn't happen, since we are Cloneable
    throw new InternalError();
}
}
...