在Java中,深克隆和浅克隆是涉及对象复制的两个概念。
-
浅克隆(Shallow Cloning):
- 浅克隆创建一个新对象,该对象与原始对象具有相同的字段值。然而,对于对象内部的引用类型字段,浅克隆将复制引用而不是引用的内容。这意味着原始对象和克隆对象将共享相同的引用对象。
- 在Java中,使用
clone()
方法来实现浅克隆。需要注意的是,被克隆的类要实现Cloneable
接口,否则会抛出CloneNotSupportedException
。
javapackage javabasic; public class Style { private String color; public String getColor() { return color; } public void setColor(String color) { this.color = color; } }
javapackage javabasic; public class Element implements Cloneable{ private String name; private Style style; // 引用另一个对象 public void init(String name, Style style){ this.name = name; this.style = style; } // 打印当前引用的style对象 public void printStyle(){ System.out.println(this.style); } @Override protected Object clone() throws CloneNotSupportedException{ return super.clone(); } }
然后可以使用:
javapackage javabasic; public class Test { public static void main(String[] args) throws CloneNotSupportedException { Style style = new Style(); style.setColor("#FF0000"); Element original = new Element(); original.init("rec",style); Element clone = (Element) original.clone(); // 打印引用的对象style,可以看到是引用了同一个对象 original.printStyle(); // javabasic.Style@4554617c clone.printStyle(); // javabasic.Style@4554617c } }
-
深克隆(Deep Cloning):
- 深克隆创建一个新对象,并尽力复制原始对象及其所有嵌套的引用类型字段,以确保原始对象和克隆对象的内部对象不共享引用。
- 实现深克隆可能涉及递归复制对象的内部引用。这可以通过手动实现
clone()
方法来实现,或者使用第三方库或序列化来处理。
javapackage javabasic; public class Style implements Cloneable{ private String color; public String getColor() { return color; } public void setColor(String color) { this.color = color; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
javapackage javabasic; public class Element implements Cloneable{ private String name; private Style style; // 引用另一个对象 public void init(String name, Style style){ this.name = name; this.style = style; } // 打印当前引用的style对象 public void printStyle(){ System.out.println(this.style); } @Override protected Object clone() throws CloneNotSupportedException{ Element clone = (Element)super.clone(); // 对于引用类型字段,执行深拷贝 clone.style = (Style) style.clone(); return clone; } }
javapackage javabasic; public class Test { public static void main(String[] args) throws CloneNotSupportedException { Style style = new Style(); style.setColor("#FF0000"); Element original = new Element(); original.init("rec",style); Element clone = (Element) original.clone(); // 打印引用的对象style,可以看到是引用的是不同的对象 original.printStyle(); // javabasic.Style@4554617c clone.printStyle(); // javabasic.Style@74a14482 } }
在这个例子中,
Style
类也需要实现Cloneable
接口,并在其clone()
方法中执行相应的深拷贝操作。
请注意,手动实现深克隆可能会变得复杂,特别是当对象包含多层嵌套引用时。在某些情况下,使用序列化和反序列化,或者使用第三方库,可能是更简单和可靠的选择。