Object的九大方法之Clone()

简介: Object的九大方法之Clone()

Object的九大方法之Clone()



使用Clone()方法的前提是要实现Cloneable接口.clone()方法就是返回一个原对象的拷贝,默认是浅拷贝,克隆的目的是复制对象,但是新的对象是独立于原来的对象的,一般我们克隆出来的对象都在一些属性做了更改,这个时候需要小心一点,如果更改的属性是引用数据类型,可能会影响到原来的对象,如果是基本数据类型则没事,使用clone()方法默认走的是浅拷贝.


浅拷贝(浅克隆)

就是复制一个对象的副本,若只需要复制对象的字段值(对于基本数据类型,如:int,long,float等,则复制值.对于复合数据类型(构造数据类型也叫对象类型)仅复制该字段值,如数组变量则复制地址值,对于对象变量则复制对象的reference


基本类型可以使用浅克隆,而对于引用类型,由于引用的是内容相同,所以改变一个实例对象中的属性将会影响到另一个对象,所以引用类型需要使用深克隆,另外,在开发一个不可变类的时候,如果这个不可变类中成员有引用类型,则就需要通过深克隆来达到不可变的目的.


深拷贝(深克隆)

深克隆与浅克隆的区别在于对符合数据类型的复制,若对象中的某个字段为复合类型,在克隆对象的时候,需要为该字段重新创造一个对象.


另一种实现方式是:序列化方式.


这种方式其实就是将对象转成二进制流,然后再把二进制流反序列化成一个java对象,这时候反序列化生成的是一个全新的对象,里面的信息与原对象一样,但是所有的内容都是一份新的.


这种方式需要注意的地方是所有类都需要实现Serializable接口,以便进行序列化操作.

public class DeepClone implements Serializable {
  private static final long serialVersionUID = 3759117094508223775L;
  protected Object deepClone() throws Exception {
    // 序列化
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ObjectOutputStream oout = new ObjectOutputStream(out);
    oout.writeObject(this);
    // 反序列化
    ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
    ObjectInputStream iin = new ObjectInputStream(in);
    Object readObject = iin.readObject();
    iin.close();
    return readObject;
  }
}
public class Person extends DeepClone{
  private static final long serialVersionUID = -5731326376902767304L;
  String name;
  int age;
  Address addr;
  public Person(String name, int age, Address addr) {
    this.name = name;
    this.age = age;
    this.addr = addr;
  }
  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 Address getAddr() {
    return addr;
  }
  public void setAddr(Address addr) {
    this.addr = addr;
  }
}
public class Address extends DeepClone {
  private static final long serialVersionUID = 2649670574270213690L;
  String address;
  String location;
  public String getAddress() {
    return address;
  }
  public void setAddress(String address) {
    this.address = address;
  }
  public String getLocation() {
    return location;
  }
  public void setLocation(String location) {
    this.location = location;
  }
  public Address(String address, String location) {
    this.address = address;
    this.location = location;
  }
  @Override
  public String toString() {
    return "Address [address=" + address + ", location=" + location + "]";
    }
}
public class Test {
  public static void main(String[] args) throws Exception {
    Person p1 = new Person("zs", 47, new Address("中国", "北京"));  
    Person p2 = (Person) p1.deepClone();
    System.out.println(p1);   
    System.out.println(p2);       
    System.out.println(p1.addr);
    System.out.println(p2.addr);  
    p2.addr.location = "上海";    
    System.out.println(p1.addr);
    System.out.println(p2.addr);    
  }
}

测试结果

cm.lhj.review02.demo1.Person@43232324
cm.lhj.review02.demo1.Person@2503dbd3
Address [address=中国, location=北京]
Address [address=中国, location=北京]
Address [address=中国, location=北京]
Address [address=中国, location=上海}

结论:深克隆是两个对象的引用,内容相同,一个对象内容的改变不会影响到另一个对象的内容.

目录
相关文章
|
7月前
|
设计模式 Java 调度
多案例理解Object的wait,notify,notifyAll与Thread的sleep,yield,join等方法
多案例理解Object的wait,notify,notifyAll与Thread的sleep,yield,join等方法
94 1
|
1月前
|
JavaScript 前端开发
`Object.create()` 方法的参数
【10月更文挑战第29天】`Object.create()` 方法的参数提供了多种创建对象和控制对象属性及继承关系的方式,开发人员可以根据具体的需求灵活运用,以实现更高效、更符合设计要求的对象创建和继承机制。
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
134 4
|
1月前
|
设计模式
在实际开发中,什么时候应该使用 `new` 关键字,什么时候应该使用 `Object.create()` 方法?
【10月更文挑战第29天】`new` 关键字适用于创建具有特定类型和初始化逻辑的对象实例,以及实现基于原型链的继承;而 `Object.create()` 方法则适用于基于现有对象创建相似对象、避免构造函数的副作用、创建具有特定原型链的对象等场景。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象,以实现更高效、更灵活的代码结构。
|
2月前
|
存储 数据采集 数据处理
Pandas中批量转换object至float的高效方法
在数据分析中,常需将Pandas DataFrame中的object类型列转换为float类型以进行数值计算。本文介绍如何使用`pd.to_numeric`函数高效转换,并处理非数字值,包括用0或平均值填充NaN值的方法。
128 1
|
2月前
|
Java 索引
Object有哪些常用方法
掌握这些方法不仅能够帮助你编写出更加健壮和高效的Java代码,还能加深对面向对象编程概念的理解。在实际开发中,合理利用 `Object`类提供的方法能够有效提升代码的可读性、可维护性和性能。
72 0
|
2月前
|
JavaScript 前端开发 大数据
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
40 0
|
4月前
|
Java
【Java基础面试二十】、介绍一下Object类中的方法
这篇文章介绍了Java中Object类的常用方法,包括`getClass()`、`equals()`、`hashCode()`、`toString()`、`wait()`、`notify()`、`notifyAll()`和`clone()`,并提到了不推荐使用的`finalize()`方法。
【Java基础面试二十】、介绍一下Object类中的方法
|
4月前
|
数据安全/隐私保护
作用域通信对象:session用户在登录时通过`void setAttribute(String name,Object value)`方法设置用户名和密码。点击登录按钮后,跳转到另外一个页面显示用户
该博客文章通过示例演示了如何使用session对象的`setAttribute`和`getAttribute`方法在不同页面间传递和显示用户的用户名和密码信息,并说明了如何设置会话的有效期。
作用域通信对象:session用户在登录时通过`void setAttribute(String name,Object value)`方法设置用户名和密码。点击登录按钮后,跳转到另外一个页面显示用户
|
4月前
|
UED 开发工具 iOS开发
Uno Platform大揭秘:如何在你的跨平台应用中,巧妙融入第三方库与服务,一键解锁无限可能,让应用功能飙升,用户体验爆棚!
【8月更文挑战第31天】Uno Platform 让开发者能用同一代码库打造 Windows、iOS、Android、macOS 甚至 Web 的多彩应用。本文介绍如何在 Uno Platform 中集成第三方库和服务,如 Mapbox 或 Google Maps 的 .NET SDK,以增强应用功能并提升用户体验。通过 NuGet 安装所需库,并在 XAML 页面中添加相应控件,即可实现地图等功能。尽管 Uno 平台减少了平台差异,但仍需关注版本兼容性和性能问题,确保应用在多平台上表现一致。掌握正确方法,让跨平台应用更出色。
62 0