Maison > Java > javaDidacticiel > le corps du texte

Exemple de tutoriel de clonage d'objets (Clone) en Java

零下一度
Libérer: 2017-07-19 10:00:01
original
1540 Les gens l'ont consulté

Partie II<br>

En ce qui concerne le clonage d'objets, nous devons expliquer pourquoi les objets doivent être clonés. Tous les objets en Java sont stockés dans le tas et le tas est partagé globalement. En d'autres termes, si différentes méthodes du même programme Java peuvent obtenir une référence à un objet, le référent peut modifier les données internes de l'objet à volonté (à condition que les données internes de l'objet soient exposées via la méthode get/set). . Parfois, le code que nous écrivons souhaite que l'appelant obtienne une seule copie de l'objet (c'est-à-dire un objet avec exactement le même contenu, mais il existe deux objets de ce type dans la mémoire). Bien sûr, c'est un clone.

Partie III

Tout d'abord, nous sommes des programmeurs, et bien sûr nous communiquons dans le langage de nos programmeurs.

import java.util.Date;
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
public class User implements Cloneable {
Copier après la connexion
	private String username;
Copier après la connexion
	private String password;
Copier après la connexion
	private Date birthdate;
Copier après la connexion
	public User(String username, String password, Date birthdate) {
Copier après la connexion
		this.username = username;
Copier après la connexion
		this.password = password;
Copier après la connexion
		this.birthdate = birthdate;
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	@Override
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	protected Object clone() throws CloneNotSupportedException {
Copier après la connexion
Copier après la connexion
		return super.clone();
Copier après la connexion
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	@Override
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	public int hashCode() {
Copier après la connexion
Copier après la connexion
		// 省略equals的实现(可用eclipse自动生成)
Copier après la connexion
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	@Override
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	public boolean equals(Object obj) {
Copier après la connexion
Copier après la connexion
		// 省略equals的实现(可用eclipse自动生成)
Copier après la connexion
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	// 省略一大堆get/set方法
Copier après la connexion
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Le code ci-dessus construit une classe User et implémente l'interface java.lang.Cloneable. Comme son nom l'indique, Cloneable signifie que cette classe peut être clonée.

Jetons d’abord un coup d’œil à ce que possède l’interface java.lang.Cloneable.

/*
Copier après la connexion
Copier après la connexion
 * @(#)Cloneable.java	1.17 05/11/17
Copier après la connexion
 *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
Copier après la connexion
Copier après la connexion
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
Copier après la connexion
Copier après la connexion
 */
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
package java.lang;
Copier après la connexion
Copier après la connexion
/**
Copier après la connexion
Copier après la connexion
 * A class implements the Cloneable interface to
Copier après la connexion
 * indicate to the {@link java.lang.Object#clone()} method that it
Copier après la connexion
 * is legal for that method to make a
Copier après la connexion
 * field-for-field copy of instances of that class.
Copier après la connexion
 *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

 * Invoking Object's clone method on an instance that does not implement the
Copier après la connexion
 * Cloneable interface results in the exception
Copier après la connexion
 * CloneNotSupportedException being thrown.
Copier après la connexion
 *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

 * By convention, classes that implement this interface should override
Copier après la connexion
 * Object.clone (which is protected) with a public method.
Copier après la connexion
 * See {@link java.lang.Object#clone()} for details on overriding this
Copier après la connexion
 * method.
Copier après la connexion
 *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

 * Note that this interface does not contain the clone method.
Copier après la connexion
 * Therefore, it is not possible to clone an object merely by virtue of the
Copier après la connexion
 * fact that it implements this interface.  Even if the clone method is invoked
Copier après la connexion
 * reflectively, there is no guarantee that it will succeed.
Copier après la connexion
 *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
 * @author  unascribed
Copier après la connexion
Copier après la connexion
 * @version 1.17, 11/17/05
Copier après la connexion
 * @see     java.lang.CloneNotSupportedException
Copier après la connexion
 * @see     java.lang.Object#clone()
Copier après la connexion
 * @since   JDK1.0
Copier après la connexion
Copier après la connexion
 */
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
public interface Cloneable {
Copier après la connexion
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ne soyez pas surpris, oui, à part pas mal d'intestins de poulet, cette interface ne définit pas n'importe quoi Signature de méthode. En d’autres termes, nous voulons cloner un objet, mais cela ne me fournit pas de méthode. Alors que faire ? N'ayez pas peur, nous avons toujours la toute-puissante classe Objet. N'oubliez pas qu'il est l'ancêtre de toutes les classes (une existence quasi divine), vous devriez donc aller le saluer chaque fois que vous avez quelque chose.

/*
Copier après la connexion
Copier après la connexion
 * @(#)Object.java	1.73 06/03/30
Copier après la connexion
 *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
Copier après la connexion
Copier après la connexion
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
Copier après la connexion
Copier après la connexion
 */
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
package java.lang;
Copier après la connexion
Copier après la connexion
/**
Copier après la connexion
Copier après la connexion
 * Class Object is the root of the class hierarchy.
Copier après la connexion
 * Every class has Object as a superclass. All objects,
Copier après la connexion
 * including arrays, implement the methods of this class.
Copier après la connexion
 *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
 * @author  unascribed
Copier après la connexion
Copier après la connexion
 * @version 1.73, 03/30/06
Copier après la connexion
 * @see     java.lang.Class
Copier après la connexion
 * @since   JDK1.0
Copier après la connexion
Copier après la connexion
 */
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
public class Object {
Copier après la connexion
    <br>
Copier après la connexion
   // 省略N多的代码
Copier après la connexion
    /**
Copier après la connexion
     * Creates and returns a copy of this object.  The precise meaning
Copier après la connexion
     * of "copy" may depend on the class of the object. The general
Copier après la connexion
     * intent is that, for any object x, the expression:
Copier après la connexion
     *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
*
Copier après la connexion
Copier après la connexion
Copier après la connexion
     * x.clone() != x
Copier après la connexion
     * will be true, and that the expression:
Copier après la connexion
     *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
*
Copier après la connexion
Copier après la connexion
Copier après la connexion
     * x.clone().getClass() == x.getClass()
Copier après la connexion
     * will be true, but these are not absolute requirements.
Copier après la connexion
     * While it is typically the case that:
Copier après la connexion
     *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
*
Copier après la connexion
Copier après la connexion
Copier après la connexion
     * x.clone().equals(x)
Copier après la connexion
     * will be true, this is not an absolute requirement.
Copier après la connexion
     *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

     * By convention, the returned object should be obtained by calling
Copier après la connexion
     * super.clone.  If a class and all of its superclasses (except
Copier après la connexion
     * Object) obey this convention, it will be the case that
Copier après la connexion
     * x.clone().getClass() == x.getClass().
Copier après la connexion
     *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

     * By convention, the object returned by this method should be independent
Copier après la connexion
     * of this object (which is being cloned).  To achieve this independence,
Copier après la connexion
     * it may be necessary to modify one or more fields of the object returned
Copier après la connexion
     * by super.clone before returning it.  Typically, this means
Copier après la connexion
     * copying any mutable objects that comprise the internal "deep structure"
Copier après la connexion
     * of the object being cloned and replacing the references to these
Copier après la connexion
     * objects with references to the copies.  If a class contains only
Copier après la connexion
     * primitive fields or references to immutable objects, then it is usually
Copier après la connexion
     * the case that no fields in the object returned by super.clone
Copier après la connexion
     * need to be modified.
Copier après la connexion
     *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

     * The method clone for class Object performs a
Copier après la connexion
     * specific cloning operation. First, if the class of this object does
Copier après la connexion
     * not implement the interface Cloneable, then a
Copier après la connexion
     * CloneNotSupportedException is thrown. Note that all arrays
Copier après la connexion
     * are considered to implement the interface Cloneable.
Copier après la connexion
     * Otherwise, this method creates a new instance of the class of this
Copier après la connexion
     * object and initializes all its fields with exactly the contents of
Copier après la connexion
     * the corresponding fields of this object, as if by assignment; the
Copier après la connexion
     * contents of the fields are not themselves cloned. Thus, this method
Copier après la connexion
     * performs a "shallow copy" of this object, not a "deep copy" operation.
Copier après la connexion
     *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

     * The class Object does not itself implement the interface
Copier après la connexion
     * Cloneable, so calling the clone method on an object
Copier après la connexion
     * whose class is Object will result in throwing an
Copier après la connexion
     * exception at run time.
Copier après la connexion
     *
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
     * @return     a clone of this instance.
Copier après la connexion
     * @exception  CloneNotSupportedException  if the object's class does not
Copier après la connexion
     *               support the Cloneable interface. Subclasses
Copier après la connexion
     *               that override the clone method can also
Copier après la connexion
     *               throw this exception to indicate that an instance cannot
Copier après la connexion
     *               be cloned.
Copier après la connexion
     * @see java.lang.Cloneable
Copier après la connexion
     */
Copier après la connexion
    protected native Object clone() throws CloneNotSupportedException;
Copier après la connexion
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Haha, une autre grosse chaîne d'intestins de poulet, ne pense pas que je suis là pour inventer le nombre de mots, ce sont toutes des technologies écrites par Développeurs Java de Sun. Articles, lisez plus et parlez moins.

Oui, c'est une méthode native. C'est effectivement une chose profonde, mais encore faut-il en profiter. De plus, sa méthode est protégée, et il nous demande clairement d'en profiter.

Continuez à regarder le code de test ci-dessous.

import java.util.Date;
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
import org.junit.Test;
Copier après la connexion
Copier après la connexion
Copier après la connexion
public class TestCase {
Copier après la connexion
Copier après la connexion
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	@Test
Copier après la connexion
Copier après la connexion
Copier après la connexion
	public void testUserClone() throws CloneNotSupportedException {
Copier après la connexion
		User u1 = new User("Kent", "123456", new Date());
Copier après la connexion
		User u2 = u1;
Copier après la connexion
		User u3 = (User) u1.clone();
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
		System.out.println(u1 == u2);		// true
Copier après la connexion
		System.out.println(u1.equals(u2));	// true
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
		System.out.println(u1 == u3);		// false
Copier après la connexion
		System.out.println(u1.equals(u3));	// true
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cette méthode clone() est vraiment géniale. Elle clone notre objet en une seule fois. Les résultats d'exécution sont également conformes à nos attentes. Les adresses de u1 et u3 sont différentes mais le contenu l'est. le même.

Partie IV

A travers l'exemple ci-dessus, nous pouvons voir qu'il y a en réalité deux étapes pour cloner un objet :

1. Laissez cette classe implémenter l'interface java.lang.Cloneable ;

2. Remplacez (remplacez) la méthode clone() de la classe Object.

Mais est-ce vraiment aussi simple ? Regardez à nouveau le code ci-dessous.

public class Administrator implements Cloneable {
Copier après la connexion
	private User user;
Copier après la connexion
	private Boolean editable;
Copier après la connexion
	public Administrator(User user, Boolean editable) {
Copier après la connexion
		this.user = user;
Copier après la connexion
		this.editable = editable;
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	@Override
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	protected Object clone() throws CloneNotSupportedException {
Copier après la connexion
Copier après la connexion
		return super.clone();
Copier après la connexion
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	@Override
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	public int hashCode() {
Copier après la connexion
Copier après la connexion
		// 老规矩
Copier après la connexion
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	@Override
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	public boolean equals(Object obj) {
Copier après la connexion
Copier après la connexion
		// 老规矩
Copier après la connexion
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	// 老规矩
Copier après la connexion
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Ce qui précède définit une classe Administrateur, qui contient un objet de classe Utilisateur. Examinons ensuite l'effet du clonage de l'objet Administrateur.

import java.util.Date;
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
import org.junit.Test;
Copier après la connexion
Copier après la connexion
Copier après la connexion
public class TestCase {
Copier après la connexion
Copier après la connexion
Copier après la connexion
	@Test
Copier après la connexion
Copier après la connexion
Copier après la connexion
	public void testAdministratorClone() throws CloneNotSupportedException {
Copier après la connexion
		Administrator a1 = new Administrator(new User("Kent", "123456", new Date()), true);
Copier après la connexion
		Administrator a2 = a1;
Copier après la connexion
		Administrator a3 = (Administrator) a1.clone();
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
		System.out.println(a1 == a2);			// true
Copier après la connexion
		System.out.println(a1.equals(a2));		// true
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
		System.out.println(a1 == a3);			// false
Copier après la connexion
		System.out.println(a1.equals(a3));		// true
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
		System.out.println(a1.getUser() == a3.getUser());		//true ! It's not our expected!!!!!
Copier après la connexion
		System.out.println(a1.getUser().equals(a3.getUser()));	//true
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Héhéhé ! Quelque chose s'est mal passé. Java est si facile à maîtriser !

Ici, nous pouvons introduire deux termes professionnels : le clone superficiel et le clone profond.

Le clonage dit superficiel, comme son nom l'indique, est un clone très superficiel Si nous voulons cloner l'objet Administrateur, nous clonons uniquement lui-même et les adresses de référence de tous les. objets qu'il contient.

Le clonage profond n'est pas un clonage superficiel. Clonez tous les objets sauf lui-même, y compris toutes les instances d'objet contenues par lui-même. Quant au niveau de clonage profond, il est déterminé par des besoins spécifiques. Il existe également un dicton de « clonage de niveau N ».

Cependant, toutes les données de type primitif, qu'il s'agisse d'un clone superficiel ou d'un clone profond, seront clonées par valeur d'origine. Après tout, ce ne sont pas des objets et ne sont pas stockés dans le tas. Remarque : Les types de données de base n'incluent pas leurs classes wrapper correspondantes.

Si nous voulons que l'objet soit profondément cloné, nous pouvons modifier la classe Administrateur comme ceci.

@Override
Copier après la connexion
protected Object clone() throws CloneNotSupportedException {
Copier après la connexion
	Administrator admin = (Administrator) super.clone();
Copier après la connexion
	admin.user = (User) admin.user.clone();
Copier après la connexion
	return admin;
Copier après la connexion
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Puisque Boolean mettra en cache la valeur, nous n'avons pas besoin de cloner l'objet booléen. Et la classe booléenne n'implémente pas l'interface java.lang.Cloneable.

Partie V

1. 让该类实现java.lang.Cloneable接口;

2. 确认持有的对象是否实现java.lang.Cloneable接口并提供clone()方法;

3. 重写(override)Object类的clone()方法,并且在方法内部调用持有对象的clone()方法;

4. ……

5. 多麻烦啊,调来调去的,如果有N多个持有的对象,那就要写N多的方法,突然改变了类的结构,还要重新修改clone()方法。

难道就没有更好的办法吗?

Part VI

接下来要重点介绍一下使用java.lang.Serializable来实现对象的深度克隆。

首先,我们编写一个工具类并提供cloneTo()方法。

import java.io.ByteArrayInputStream;
Copier après la connexion
import java.io.ByteArrayOutputStream;
Copier après la connexion
import java.io.IOException;
Copier après la connexion
import java.io.ObjectInputStream;
Copier après la connexion
import java.io.ObjectOutputStream;
Copier après la connexion
public abstract class BeanUtil {
Copier après la connexion
	@SuppressWarnings("unchecked")
Copier après la connexion
	public static  T cloneTo(T src) throws RuntimeException {
Copier après la connexion
		ByteArrayOutputStream memoryBuffer = new ByteArrayOutputStream();
Copier après la connexion
		ObjectOutputStream out = null;
Copier après la connexion
		ObjectInputStream in = null;
Copier après la connexion
		T dist = null;
Copier après la connexion
		try {
Copier après la connexion
			out = new ObjectOutputStream(memoryBuffer);
Copier après la connexion
			out.writeObject(src);
Copier après la connexion
			out.flush();
Copier après la connexion
			in = new ObjectInputStream(new ByteArrayInputStream(memoryBuffer.toByteArray()));
Copier après la connexion
			dist = (T) in.readObject();
Copier après la connexion
		} catch (Exception e) {
Copier après la connexion
			throw new RuntimeException(e);
Copier après la connexion
		} finally {
Copier après la connexion
			if (out != null)
Copier après la connexion
				try {
Copier après la connexion
Copier après la connexion
					out.close();
Copier après la connexion
					out = null;
Copier après la connexion
				} catch (IOException e) {
Copier après la connexion
Copier après la connexion
					throw new RuntimeException(e);
Copier après la connexion
Copier après la connexion
				}
Copier après la connexion
Copier après la connexion
			if (in != null)
Copier après la connexion
				try {
Copier après la connexion
Copier après la connexion
					in.close();
Copier après la connexion
					in = null;
Copier après la connexion
				} catch (IOException e) {
Copier après la connexion
Copier après la connexion
					throw new RuntimeException(e);
Copier après la connexion
Copier après la connexion
				}
Copier après la connexion
Copier après la connexion
		}
Copier après la connexion
		return dist;
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

看不懂,没关系,直接拿去用就可以了。嘻嘻。

接下来我们测试一下是否能通过这个工具来实现深度克隆。

又是这个可爱的TestCase,可怜的每次都要动他……

import java.util.Date;
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
import org.junit.Test;
Copier après la connexion
Copier après la connexion
Copier après la connexion
public class TestCase {
Copier après la connexion
Copier après la connexion
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
	@Test
Copier après la connexion
Copier après la connexion
Copier après la connexion
	public void testCloneTo() {
Copier après la connexion
		Administrator src = new Administrator(new User("Kent", "123456", new Date()), true);
Copier après la connexion
		Administrator dist = BeanUtil.cloneTo(src);
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
		System.out.println(src == dist);			// false
Copier après la connexion
		System.out.println(src.equals(dist));		// true
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
		System.out.println(src.getUser() == dist.getUser());		//false ! Well done!
Copier après la connexion
		System.out.println(src.getUser().equals(dist.getUser()));	//true
Copier après la connexion
	}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
<br>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

好了,无论你的对象有多么的复杂,只要这些对象都能够实现java.lang.Serializable接口,就可以进行克隆,而且这种克隆的机制是JVM完成的,不需要修改实体类的代码,方便多了。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal