2011-11-19 16 views
11

para clonar el objeto ¿Necesito implementar la interfaz 'clonable'? porque aquí mi clase es un archivo jar (me refiero a API). entonces no puedo editar la clase Escuché que todas las clases amplían la clase de objetos base y esta clase de objetos implementa la interfaz clonable. ¿eso significa que podemos clonar directamente el objeto sin implementar la interfaz? si es así en mi eclipse, no tengo la opción de clonar el objeto. hay otra forma de clonar el objeto sin implementar la interfaz clonable. por favor explique.clonación de objetos sin implementar la interfaz clonable

+1

¿Por qué sientes que debes hacer esto? Tal vez sea mejor que nos cuente el problema general que intenta resolver en lugar de los pasos de programación que cree que podrían ser necesarios para resolverlo. En otras palabras, puede estar haciendo las cosas mal. –

+0

Por los comentarios en las respuestas, creo que el OP quiere un constructor de copia. – msandiford

+0

ho hovercraft. Aquí estoy explicando mi problema claramente. tengo una clase llamada XYZ y tengo un método que devuelve un objeto de esta clase XYZ. private XYZ getObject() {return obj; } y creé un objeto llamando a este método. XYZ obj1 = getObject(); aquí viene el problema De hecho, quiero crear un objeto más sin volver a llamar al método. y no puedo editar la clase XYZ aquí. quería hacer XYZ obj2 = (XYZ) obj1.clone(); pero no puedo implementar la interfaz "clonable" en mi clase XYZ. entonces hay alguna otra forma de crear un objeto más para esta clase. – ran

Respuesta

5

la clase Java Object no implementa la interfaz Cloneable. Sin embargo, tiene el método clone(). Pero este método es protected y lanzará CloneNotSupportedException si se llama a un objeto que no implementa la interfaz Cloneable. Entonces, si no puede modificar la clase que desea clonar, no tiene suerte y deberá buscar otra forma de copiar la instancia.

Sin embargo, debe tenerse en cuenta que el sistema clónico en Java está lleno de agujeros y generalmente ya no se usa. Consulte este interview con Josh Bloch de 2002 explicando algunos de los problemas.

+0

¿Hay alguna otra forma de clonar el objeto sin implementar la interfaz clonable? ... gracias por su respuesta – ran

+0

"Sin embargo, debe tenerse en cuenta que el sistema de clonación en Java está lleno de agujeros y, en general, ya no se usa". - ¿Puedes agregar una referencia para la declaración? –

+0

Puede crear una nueva instancia usando un constructor y copiar el estado requerido. La viabilidad de esto realmente depende de la clase de objeto que desea copiar. – orien

0

Al intentar invocar el método de clonación en una clase que no implementa Cloneable lanza la Excepción CloneNotSupported y ninguna clase de Objeto no implementa Cloneable.

aquí es el Javadoc del método clon de la clase de objeto

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. 

También método objeto # clon está protegido por lo que necesita para implementar el método clone en su clase y hacerlo público para que pueda ser accesible a clases que crean objetos de tu clase que pueden invocar el clon. Un buen ejemplo es la forma clon es implementar en ArrayList

ArrayList implementa cloneable, como a continuación ArrayList clase pública se extiende AbstractList implementa Lista, acceso aleatorio, Cloneable, java.io.Serializable

y luego implementa el método 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(); 
} 
} 
+0

hola gaurav, como ya he mencionado, no puedo implementar la interfaz clonable en mi clase. pero quiero crear el objeto duplicado con un nombre diferente del objeto existente. Hay alguna otra manera de hacer esto. – ran

+0

Si me preguntas si puedes clonar un objeto de una clase que no puedes editar. La respuesta es no. Teóricamente, puede usar la reflexión para acceder a las variables de la clase y así poder obtener y replicar su estado, pero depende del administrador de seguridad si puede acceder a los miembros privados de la clase. Nuevamente, incluso en ese caso, la copia profunda puede no ser posible. –

+0

Probablemente deberías usar un constructor de copia en este caso en lugar de 'clone()'. El primer enlace en Google es este: http://www.javapractices.com/topic/TopicAction.do?Id=12 – msandiford

0

El método clone() en la clase Object está protegido, lo que significa que todas las clases lo heredan con el modificador de acceso protegido, por lo tanto, si intenta acceder fuera de esa clase sin clonarlo no lo verá, también le lanzará CloneNotSupportedException si intenta invocarlo sin implementar la interfaz Cloneable.

En caso de que esté buscando crear un comportamiento de clon, debe escribir un nuevo método en su clase y luego crear una copia de todos los campos en eso, básicamente es como crear una nueva copia de un estado existente de un objeto.

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; 
} 

}

5

por lo general es la mejor práctica para evitar clone() de todos modos, porque es difícil de hacer correctamente (http://www.javapractices.com/topic/TopicAction.do?Id=71). Tal vez la clase en cuestión tiene un constructor de copia?

Alternativamente, si se implementa Serializable o Externalizable, a lo más profundo puede copiarlo, escribiéndolos en un flujo de bytes y leyendo de nuevo en

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(); 

(desde http://www.jguru.com/faq/view.jsp?EID=20435).Esto es rápido y fácil, pero no es bonito ... En general, lo consideraría un último recurso.

+0

hi kyle. gracias por su respuesta. pero no entendí exactamente sobre esto. ¿Puedes decirme en mi caso cómo puedo hacerlo? – ran

+0

Un constructor de copia se vería así: public XYZ (XYZ toCopy). En lugar de llamar a o.clone(), llamarías a XYZ (o) nuevo. La parte serializable significa que si XYZ se puede escribir en una secuencia, puede escribirla en una secuencia (en realidad solo una serie de bytes en la memoria) y luego leerla desde esa secuencia, creando efectivamente una copia. – kylewm

+0

La limitación de un constructor de copia es que necesita saber el tipo de clase en el momento de la creación del código. 'public XYZ (toCopy)' no funcionará si paso una subclase de 'XYZ'. –

0

No es obligatorio para implementar la interfaz cloneable para hacer un clon de un objeto. Puede escribir su propio método de clonación en la clase cuyo objeto desea clonar.

+1

Esto no proporciona una respuesta a la pregunta. Una vez que tenga suficiente [reputación] (https://stackoverflow.com/help/whats-reputation) podrá [comentar cualquier publicación] (https://stackoverflow.com/help/privileges/comment); en su lugar, [proporcione respuestas que no requieran aclaración del solicitante] (https: //meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [De la opinión] (/ reseña/mensajes de baja calidad/18867158) –

Cuestiones relacionadas