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 ...
随机推荐
- Leetcode 算法题
lEETCODE 算法题 0013 罗马数字转整数
- egrep 正则
首先要记住的是: 正则表达式与通配符不一样,它们表示的含义并不相同!正则表达式只是一种表示法,只要工具支持这种表示法, 那么该工具就可以处理正则表达式的字符串.vim.grep.awk .sed 都支 ...
- spring中配置Properties对象的方法
工作中有必要将Properties对象进行注解进入:比如 class Person{ @Autowired private Properties properties; } 如果有这种需求的话,那么需 ...
- WebService发送 方法
public String disableSaleOut(JSONObject jsonObject) throws ServiceException, MalformedURLException, ...
- 前端跨域之jsonp
demo1: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- synchronized(this) 与 synchronized(class) 理解
1.概念 synchronized 是 Java 中的关键字,是利用锁的机制来实现同步的. 锁机制有如下两种特性: 互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机 ...
- PHP FILTER_SANITIZE_ENCODED 过滤器
定义和用法 FILTER_SANITIZE_ENCODED 过滤器去除或 URL 编码不需要的字符. 该过滤器与 urlencode() 函数很类似. Name: "encoded" ...
- 基础(三):yum(RedHat系列)和apt-get(Debian系列 )用法及区别
文章转载来自:http://blog.csdn.net/chengly0129/article/details/70169760 一般来说著名的linux系统基本上分两大类:1.RedHat系列:Re ...
- python内置模块-random
print(random.randint(1,10)) 生成随机整数,下限必须小于上限print(random.randrange(1,10)) 生成随机整数,参数为([start],stop,[st ...
- myeclipse 启动卡住的解决办法
myeclipse 启动卡住的解决办法 今天启动myeclipse突然卡住,CPU一直占用,启动任务管理器强制关闭.重启myeclipse,重启电脑都不能够解决. 上网查找,在工程路径(工作空间的路径 ...