java拷贝--clone
大纲:
- java如何拷贝对象。
- 浅拷贝
- 深拷贝
一、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的更多相关文章
- Java基础——clone()方法浅析
一.clone的概念 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- 分析java中clone()方法 (转载+修改)
Java中的clone() 方法 java所有的类都是从java.lang.Object类继承而来的,而Object类提供下面的方法对对象进行复制. protected native Object c ...
- java中clone的深入理解
Java中Clone的概念大家应该都很熟悉了,它可以让我们很方便的“制造”出一个对象的副本来,下面来具体看看java中的Clone机制是如何工作的? 1. Clone和Copy 假 ...
- Java中clone方法的使用
什么是clone 在实际编程过程中,我们常常要遇到这种情况:有一个对象object1,在某一时刻object1中已经包含了一些有效值,此时可能会需要一个和object1完全相同新对象object2,并 ...
- Java的clone方法效率问题
在Java中,经常会需要新建一个对象,很多情况下,需要这个新建的对象和现有的某个对象保持属性一致. 那么,就有两种方式来实现这个对象的构造: ①通过新建一个对象,为这个对象的属性根据原有对象的属性来进 ...
- Java Object Clone
Java Object Clone User user = new User(); user.setName("tom"); User user1 = new User(); us ...
- Javascript对象拷贝(clone)
Javascript对象拷贝(clone),希望大家给点建议1. [代码]方法代码 function cp(source, target) { function isBaseType(v) { ...
- java拷贝字符文件
1.java拷贝字符文件 2.代码如下: package Demo1; import java.io.*; public class copyfile { public static void mai ...
- java 拷贝功能
java 中的 拷贝分为浅拷贝 和 深拷贝 浅拷贝需要实现Cloneable接口,深拷贝需要实现Serializable接口. public class Square implements Clone ...
随机推荐
- 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 ...
- KMP 算法学习
KMP算法是用来做字符串匹配的.关于字符串匹配,最简单最容易想到的方法是暴利查找,使用双重for循环处理. 该方法的时间复杂度为O((n-m+1)*m) (n为目标串T长度,m为模式串P长度, 从T中 ...
- 运行连接Oracle数据库时,Idea报错: Error : java 不支持发行版本5
按照上面的截图步骤,一步步往下走,再运行程序时就不会报错了. 原文链接:https://blog.csdn.net/qq_22076345/article/details/82392236 感谢原文作 ...
- 获取本机IP,本机名称
InetAddress addr = InetAddress.getLocalHost(); ip=addr.getHostAddress().toString;//获得本机IP address=ad ...
- APICloud框架——获取本地图片信息
api.getPicture 获取本地图片放置到服务器上或者在app中预览是app的基本功能,今天使用了APICloud框架的api.getPicture这个api获取到的本地图片预览在app中,就像 ...
- 127.0.0.1和localhost不能正确映射的问题
可能引起的问题: 检查:分别ping一下127.0.0.1和localhost 以上是正确演示,不匹配的话,ping localhost会返回: 解决方案: 可能1: 在浏览器中打开http://12 ...
- js设计模式——6.模板方法模式与职责链模式
js设计模式——6.模板方法模式与职责链模式 职责链模式
- Linux初上手!
虚拟机Virtual Box装的Kali Linux,是Debian的发行版本,安装过程不说了,不是硬盘安装也没什么说的,由于是新手所以只有两个分区,一个[/]和一个[swap] 装好之后是xwind ...
- C#调用Mail发送QQ邮件
需要用到: 1.System.Net.Mail; 2.QQ邮箱的POP3/SMTP服务码 QQ邮箱的POP3/SMTP服务码获取方法: 1.打开qq邮箱: 2.进入设置页面-->账户:(往下翻) ...
- C++——数据类型选择
1.数据类型选择推荐 2.数据类型相关代码注意 2.1 循环的int型注意是int 还是unsigned unsigned a=-1;(a=4294967295)