MST

星途 面试题库

面试题:Java原型模式在复杂对象克隆中的应用

假设有一个复杂的Java对象,该对象内部包含多个引用类型的成员变量,如List、Map等,且这些成员变量也有各自复杂的结构。请描述如何在这种情况下正确应用原型模式进行对象克隆,避免浅拷贝问题,并给出关键代码示例。
35.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 应用原型模式避免浅拷贝的方法
    • 实现Cloneable接口:Java的原型模式基于Cloneable接口,要克隆的类必须实现这个接口。
    • 重写clone方法:在类中重写clone方法,对于引用类型的成员变量,需要进行深拷贝。对于List,可以遍历原List,逐个克隆元素并添加到新List;对于Map,可以遍历原Map的键值对,对值进行克隆后放入新Map
  2. 关键代码示例
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class InnerClass implements Cloneable {
    private int value;

    public InnerClass(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class ComplexObject implements Cloneable {
    private List<InnerClass> list;
    private Map<String, InnerClass> map;

    public ComplexObject() {
        list = new ArrayList<>();
        map = new HashMap<>();
    }

    public void addToList(InnerClass inner) {
        list.add(inner);
    }

    public void addToMap(String key, InnerClass inner) {
        map.put(key, inner);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        ComplexObject clone = (ComplexObject) super.clone();
        clone.list = new ArrayList<>();
        for (InnerClass inner : list) {
            clone.list.add((InnerClass) inner.clone());
        }
        clone.map = new HashMap<>();
        for (Map.Entry<String, InnerClass> entry : map.entrySet()) {
            clone.map.put(entry.getKey(), (InnerClass) entry.getValue().clone());
        }
        return clone;
    }
}

可以通过以下方式测试:

public class Main {
    public static void main(String[] args) {
        try {
            ComplexObject original = new ComplexObject();
            InnerClass inner1 = new InnerClass(1);
            InnerClass inner2 = new InnerClass(2);
            original.addToList(inner1);
            original.addToMap("key1", inner2);

            ComplexObject clone = (ComplexObject) original.clone();

            // 修改克隆对象中的内容,验证深拷贝
            clone.list.get(0).setValue(10);
            clone.map.get("key1").setValue(20);

            System.out.println("Original List value: " + original.list.get(0).getValue());
            System.out.println("Original Map value: " + original.map.get("key1").getValue());
            System.out.println("Clone List value: " + clone.list.get(0).getValue());
            System.out.println("Clone Map value: " + clone.map.get("key1").getValue());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

上述代码中,ComplexObject类包含ListMap类型的成员变量,且这些成员变量中存储的是自定义的InnerClass对象。通过重写clone方法,对ListMap中的元素进行深拷贝,从而避免了浅拷贝问题。