Maison >Java >JavaQuestions d'entretien >Questions d'entretien courantes sur la copie d'objets Java
Pourquoi recourir au clonage ? (Apprentissage recommandé : Questions du test commun Java )
Si vous souhaitez gérer un objet et que vous souhaitez conserver les données d'origine pour l'opération suivante, vous devez le cloner , java Le clonage dans le langage concerne les instances de classes.Comment mettre en œuvre le clonage d'objets ?
Il existe deux manières :
d'implémenter l'interface Cloneable et de remplacer la méthode clone() dans la classe Object ; et la désérialisation pour réaliser le clonage, qui peut réaliser un véritable clonage profond. Le code est le suivant :import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class MyUtil { private MyUtil() { throw new AssertionError(); } @SuppressWarnings("unchecked") public static <T extends Serializable> T clone(T obj) throws Exception { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bout); oos.writeObject(obj); ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bin); return (T) ois.readObject(); // 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义 // 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放 } }
Voici le code de test :
import java.io.Serializable; /** * 人类 * @author nnngu * */ class Person implements Serializable { private static final long serialVersionUID = -9102017020286042305L; private String name; // 姓名 private int age; // 年龄 private Car car; // 座驾 public Person(String name, int age, Car car) { this.name = name; this.age = age; this.car = car; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", car=" + car + "]"; } }
/** * 小汽车类 * @author nnngu * */ class Car implements Serializable { private static final long serialVersionUID = -5713945027627603702L; private String brand; // 品牌 private int maxSpeed; // 最高时速 public Car(String brand, int maxSpeed) { this.brand = brand; this.maxSpeed = maxSpeed; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } @Override public String toString() { return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]"; } }
class CloneTest { public static void main(String[] args) { try { Person p1 = new Person("郭靖", 33, new Car("Benz", 300)); Person p2 = MyUtil.clone(p1); // 深度克隆 p2.getCar().setBrand("BYD"); // 修改克隆的Person对象p2关联的汽车对象的品牌属性 // 原来的Person对象p1关联的汽车不会受到任何影响 // 因为在克隆Person对象时其关联的汽车对象也被克隆了 System.out.println(p1); } catch (Exception e) { e.printStackTrace(); } } }
Remarque. : Le clonage basé sur la sérialisation et la désérialisation n'est pas seulement un clonage profond, mais plus important encore, grâce à une qualification générique, vous pouvez vérifier si l'objet à cloner prend en charge la sérialisation. Cette vérification est effectuée par le compilateur, pas au moment de l'exécution. exception, cette solution est évidemment meilleure que d'utiliser la méthode clone de la classe Object pour cloner l'objet. Il est toujours préférable d'exposer les problèmes au moment de la compilation plutôt que de les laisser au moment de l'exécution.
Quelle est la différence entre la copie profonde et la copie superficielle ?
La copie superficielle copie uniquement l'adresse de référence de l'objet. Les deux objets pointent vers la même adresse mémoire, donc si une valeur est modifiée, l'autre valeur changera en conséquence. exemple : assign()) la copie profonde consiste à copier l'objet et sa valeur. Si une valeur des deux objets est modifiée, l'autre valeur ne sera pas modifiée (par exemple : JSON.parse() et). JSON.stringify(), mais cette méthode ne peut pas copier le type de fonction)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!