大纲:

  1. java如何拷贝对象。
  2. 浅拷贝
  3. 深拷贝

一、java如何拷贝对象

Person p = new Person();
Person p2 = p;

上例并不是一个拷贝操作,只是把p对象的引用赋给了p2,2个变量指向了同一片heap地址。

想实现拷贝操作需要做2件事情:

(1)实现Cloneable接口,这是一个空接口不用重写任何方法。

public interface Cloneable {}

(2)重写clone方法,注意clone方法是Object类中的native方法,并不是Cloneable接口的。

二、浅拷贝

改写Person类

@Data
public class Person implements Cloneable {
private String name;
private int age;
private Date birth; @Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", birth=" + birth.getTime() +
'}';
} @Override
public Person clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {}
return (Person)clone;
}
}

调用clone方法复制对象:

Person p1 = new Person();
Person p2 = p1.clone();

这样p1,p2就不是一个对象了。

三、深拷贝

以上Person对象中的成员变量都是java原生对象和基础数据类型,浅拷贝足以使Person拥有拷贝的功能。

如果为Person加上一个自定类的成员变量

@Data
public class Father {
private String name;
private int age; @Override
public String toString() {
return "Father{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Person implements Cloneable {
private String name;
private int age;
private Date birth;
private Father father;
}

这样做后person中的father对象无法实现拷贝

测试例:

public static void main(String[] args){
Person p1 = new Person();
p1.setName("p1");
Father f1 = new Father();
f1.setName("f1");
p1.setFather(f1);
Person p2 = (Person) p1.clone();
p2.getFather().setName("f2");
p2.setName("p2");
System.out.println(p1);
System.out.println(p2); //结果
//Person{name='p1', age=0, birth=null, father=Father{name='f2', age=0}}
//Person{name='p2', age=0, birth=null, father=Father{name='f2', age=0}}
}

可以看到person对象实现了拷贝,但是father对象还是引用了同一个对象。

深拷贝实现步骤:

(1)使自定义的类的成员变量实现Cloneable接口并重写clone方法。

@Data
public class Father implements Cloneable{
private String name;
private int age; @Override
public String toString() {
return "Father{" +
"name='" + name + '\'' +
", age=" + age +
'}';
} @Override
public Father clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {}
return (Father) clone;
}
}

(2)成员变量重写clone方法后,还需要将成员变量的拷贝对象显式赋值。

@Data
public class Person implements Cloneable {
private String name;
private int age;
private Date birth;
private Father father; @Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", birth=" + birth +
", father=" + father +
'}';
} @Override
public Person clone() {
Person clone = null;
try {
clone = (Person) super.clone();
} catch (CloneNotSupportedException e) {}
//这里显式赋值
if(father!=null){
clone.setFather(father.clone());
}
return clone;
}
}

至此person中的father变量也完成了拷贝,可用上面的测试例子验证一下。

public static void main(String[] args){
Person p1 = new Person();
p1.setName("p1");
Father f1 = new Father();
f1.setName("f1");
p1.setFather(f1);
Person p2 = (Person) p1.clone();
p2.getFather().setName("f2");
p2.setName("p2");
System.out.println(p1);
System.out.println(p2);
//结果
//Person{name='p1', age=0, birth=null, father=Father{name='f1', age=0}}
//Person{name='p2', age=0, birth=null, father=Father{name='f2', age=0}}
}

java拷贝--clone的更多相关文章

  1. Java基础——clone()方法浅析

    一.clone的概念 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...

  2. 分析java中clone()方法 (转载+修改)

    Java中的clone() 方法 java所有的类都是从java.lang.Object类继承而来的,而Object类提供下面的方法对对象进行复制. protected native Object c ...

  3. java中clone的深入理解

    Java中Clone的概念大家应该都很熟悉了,它可以让我们很方便的“制造”出一个对象的副本来,下面来具体看看java中的Clone机制是如何工作的?      1. Clone和Copy      假 ...

  4. Java中clone方法的使用

    什么是clone 在实际编程过程中,我们常常要遇到这种情况:有一个对象object1,在某一时刻object1中已经包含了一些有效值,此时可能会需要一个和object1完全相同新对象object2,并 ...

  5. Java的clone方法效率问题

    在Java中,经常会需要新建一个对象,很多情况下,需要这个新建的对象和现有的某个对象保持属性一致. 那么,就有两种方式来实现这个对象的构造: ①通过新建一个对象,为这个对象的属性根据原有对象的属性来进 ...

  6. Java Object Clone

    Java Object Clone User user = new User(); user.setName("tom"); User user1 = new User(); us ...

  7. Javascript对象拷贝(clone)

    Javascript对象拷贝(clone),希望大家给点建议​1. [代码]方法代码 function cp(source, target) {    function isBaseType(v) { ...

  8. java拷贝字符文件

    1.java拷贝字符文件 2.代码如下: package Demo1; import java.io.*; public class copyfile { public static void mai ...

  9. java 拷贝功能

    java 中的 拷贝分为浅拷贝 和 深拷贝 浅拷贝需要实现Cloneable接口,深拷贝需要实现Serializable接口. public class Square implements Clone ...

随机推荐

  1. MyEclipse中android 项目如何解决第三方jar无法关联源码的问题( The JAR of this class file belongs to container 'Android Private Libraries' which does not allow modifications to source attachments on its entries.)

    若我们要为第三方jar(android-support-v4.jar)关联源码通常的做法是 右键项目 单击菜单Properties 单击菜单 Java Build Path 单击 Libraries ...

  2. KMP 算法学习

    KMP算法是用来做字符串匹配的.关于字符串匹配,最简单最容易想到的方法是暴利查找,使用双重for循环处理. 该方法的时间复杂度为O((n-m+1)*m) (n为目标串T长度,m为模式串P长度, 从T中 ...

  3. 运行连接Oracle数据库时,Idea报错: Error : java 不支持发行版本5

    按照上面的截图步骤,一步步往下走,再运行程序时就不会报错了. 原文链接:https://blog.csdn.net/qq_22076345/article/details/82392236 感谢原文作 ...

  4. 获取本机IP,本机名称

    InetAddress addr = InetAddress.getLocalHost(); ip=addr.getHostAddress().toString;//获得本机IP address=ad ...

  5. APICloud框架——获取本地图片信息

    api.getPicture 获取本地图片放置到服务器上或者在app中预览是app的基本功能,今天使用了APICloud框架的api.getPicture这个api获取到的本地图片预览在app中,就像 ...

  6. 127.0.0.1和localhost不能正确映射的问题

    可能引起的问题: 检查:分别ping一下127.0.0.1和localhost 以上是正确演示,不匹配的话,ping localhost会返回: 解决方案: 可能1: 在浏览器中打开http://12 ...

  7. js设计模式——6.模板方法模式与职责链模式

    js设计模式——6.模板方法模式与职责链模式 职责链模式

  8. Linux初上手!

    虚拟机Virtual Box装的Kali Linux,是Debian的发行版本,安装过程不说了,不是硬盘安装也没什么说的,由于是新手所以只有两个分区,一个[/]和一个[swap] 装好之后是xwind ...

  9. C#调用Mail发送QQ邮件

    需要用到: 1.System.Net.Mail; 2.QQ邮箱的POP3/SMTP服务码 QQ邮箱的POP3/SMTP服务码获取方法: 1.打开qq邮箱: 2.进入设置页面-->账户:(往下翻) ...

  10. C++——数据类型选择

    1.数据类型选择推荐 2.数据类型相关代码注意 2.1 循环的int型注意是int 还是unsigned unsigned a=-1;(a=4294967295)