java:clone
一,为什么要使用clone
在实际编程过程中,我们常常遇到这种情况:有一个对象 A,需要一个和 A 完全相同新对象 B,并且此后对 B 任何改动都不会影响到 A 中的值,也就是说,A 与 B 是两个独立的对象,但 B 的初始值是由 A 对象确定的。在 Java 语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需
求虽然有很多途径,但实现 clone()方法是其中最简单,也是最高效的手段。
二,new和clone的区别
new
• 通过调用类的构造函数来创建新对象实例,这意味着可以定义对象的初始化状态
• 根据对象类型明确分配相应大小的内存空间
• 需要显式初始化,通常在构造函数中完成
• 涉及内存分配、构造函数调用和初始化,可能在复杂对象中相对较慢
• 不依赖已有对象,每次创建都是全新的实例
• 无需实现任何特殊接口
• 用于全新创建对象实例,无历史状态需求
• 生成完全独立的对象,互不影响
clone
• 不会调用构造函数,而是复制已有对象的属性,适用于快速创建一个具有相似状态的对象
• 分配内存给新对象,并且大小与原对象相同
• 继承了原对象的初始化状态,不需要再次初始化
• 通常认为较快,因为避免了构造函数调用和逐步初始化,但具体取决于JVM实现和场景
• 必须有一个原对象作为克隆的基础
• 需要实现Cloneable接口并重写clone()方法,否则会抛出CloneNotSupportedException异常
• 用于基于现有对象快速生成一个副本,例如保存当前状态进行操作或比较
• 虽然生成的是一个新对象,但如果涉及到引用类型字段,则需要深拷贝处理,否则可能存在依赖
三, 复制对象和复制引用的区别


四,浅拷贝和深拷贝
在Java编程中,clone()方法提供了一种创建对象副本的方式。通过实现Cloneable接口并重写clone()方法,我们可以轻松地创建一个对象的完整复制品。然而,关于使用clone()方法,存在许多细节和注意事项,尤其是在处理浅克隆(shallow copy)与深克隆(deep copy)时。本篇博客将深入探讨这一主题。
在Java中,所有对象都继承自Object类,其中包含一个clone()方法,但该方法是受保护的(protected),意味着我们不能直接在非子类外部调用它。为了使得clone()方法可用,我们需要实现Cloneable接口,该接口是一个标记接口(marker interface),本身不包含任何方法,说明这个类可拷贝。
实现Cloneable接口后,我们可以通过重写clone()方法来提供自定义的复制逻辑。如果不重写clone()方法,对象将获得一个默认的浅复制行为,这意味着基本字段将被复制,但引用类型字段将只复制引用,而不是引用的对象
浅拷贝
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}可以看到后面需要加上一个抛异常的代码,而且clone返回类型是Object
深拷贝
protected Object clone() throws CloneNotSupportedException {
//return super.clone();
Person tmp = (Person) super.clone();
tmp.m = (Money) this.m.clone();
return tmp;
}
class Money implements Cloneable{
public double money = 19.9;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable{
public int age;
public Money m;
public Person(int age) {
this.age = age;
this.m = new Money();
}
@Override
protected Object clone() throws CloneNotSupportedException {
//return super.clone();
Person tmp = (Person) super.clone();
tmp.m = (Money) this.m.clone();
return tmp;
}
@Override
public String toString() {
return "Person{" +
" age=" + age +
'}';
}
}
public class Test2 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person(10);
Person person2 = (Person)person1.clone();
System.out.println(person1.m.money);
System.out.println(person2.m.money);
System.out.println("==========================");
person2.m.money = 99.99;
System.out.println(person1.m.money);
System.out.println(person2.m.money);
}
}

更多推荐


所有评论(0)