Клонирование объектов без реализации клонируемого интерфейса

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

Ответ 1

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

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

Ответ 2

Как правило, лучше избегать клонирования(), так как это трудно сделать правильно (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). Это быстро и легко, но не очень... Я бы вообще считал это последней инстанцией.

Ответ 4

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

вот javadoc из метода clone класса Object

CloneNotSupportedException  if the object 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 в своем классе и сделать его общедоступным, чтобы он мог быть доступен для классов, создающих объекты вашего класса, которые затем могут вызвать клонирование. Хорошим примером является способ реализации клона в ArrayList

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

а затем реализует метод clone: ​​

/**
 * 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();
}
}

Ответ 5

Метод 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;
}

}

Ответ 6

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