Поскольку метод clone
помечен как protected
в классе Object
, вы вообще не можете вызывать этот метод для произвольных объектов.Идея метода clone()
заключается в том, что классы, которые его поддерживают, переопределяют метод, объявляя его открытым.
Единственное реальное решение, сохраняющее полную функциональность, - это использование отражения для доступа к методу и его обхода.модификаторы доступа.
Итак, вот мое решение,
public class B<E extends Cloneable> {
E data;
public B(E elem) {
this.data = elem;
}
@SuppressWarnings("unchecked")
public E get() {
Method clone = null;
try {
clone = data.getClass().getMethod("clone");
Object[] args = new Object[0];
return (E) clone.invoke(data, args);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
Clonable
определяет поведение реализации защищенного клона объекта: если класс реализует Cloneable
, метод клона объекта возвращает поле-полевой копии объекта;в противном случае выдает CloneNotSupportedException
.Но способ, которым вы реализовали метод клонирования в классе A
, не вызывает метод Object's
clone
, так что это не имеет никакого эффекта.
@Override
public A clone() throws CloneNotSupportedException {
A temp = new A(this.value, this.name);
return temp;
}
Если вы хотите использовать это средство, у вас естьчтобы реализовать это так,
public class A implements Cloneable {
int value;
String name;
public A(int x, String str) {
this.value = x;
this.name = str;
}
@Override
public A clone() throws CloneNotSupportedException {
return (A) super.clone();
}
public boolean equals(A elem) {
return (this.name).equals(elem.name) && this.value == elem.value;
}
}
В этом случае, если ваш класс A
не реализует Cloneable
, тогда java.lang.CloneNotSupportedException
будет выброшено.
Наконец, объявление public class B<E extends Cloneable>
дает вам ошибку компилятора, если вы попытаетесь передать что-то, что не реализует Cloneable
, конструктору B
в вашем классе Demo
.
B<A> c = new B<>(doesNotImplCloneable); // Gives a compilation error.
Так что, если вы используете метод клонирования Объекта, как я показал здесь, extends/implements Cloneable
- это путь.