Maison >Java >JavaQuestions d'entretien >Questions d'entretien sur les nouvelles Java 2020 - Copie d'objet

Questions d'entretien sur les nouvelles Java 2020 - Copie d'objet

王林
王林avant
2020-06-13 17:04:452082parcourir

Questions d'entretien sur les nouvelles Java 2020 - Copie d'objet

1.Pourquoi recourir au clonage ?

Si vous souhaitez traiter un objet et conserver les données d'origine pour les opérations ultérieures, vous devez le cloner en langage Java cible les instances de classes.

2. Comment mettre en œuvre le clonage d'objets ?

Il existe deux manières :

(Tutoriel recommandé : Programme d'entrée Java)

(1) Implémenter l'interface Cloneable et réécrire l'objet La méthode clone() dans la classe ;

(2) Implémentez l'interface Serialisable et implémentez le clonage via la sérialisation et la désérialisation des objets, qui peuvent 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 est Prend en charge la sérialisation. Cette vérification est effectuée par le compilateur et ne lève pas d'exception au moment de l'exécution. 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.

(Tutoriel vidéo recommandé : Tutoriel vidéo Java)

3. 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. Il s'agit d'une copie complète (par exemple : JSON.parse() et JSON. stringify(), mais cette méthode ne peut pas copier les types de fonctions)

Plus de recommandations de questions d'entretien : questions d'entretien Java

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer