java对象拷贝和复制
参考文章:http://blog.csdn.net/XIAXIA__/article/details/41652057
解决问题:深拷贝、浅拷贝 和普通的对象赋值有什么区别?
对象复制
例如:Person p2 = p1;实质就是对象地址复制。把p1地址赋值给p2。此时二者同时指向一块堆内存,所以改变p1的属性值之后,p2所对应的属性值也会跟着变化。
例如有一个如下所示的Person类:
package tudou.javabasic.clone;
class Person {
private int age;
private String name;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
Person
执行如下代码:
public class CloneTest {
public static void main(String[] args) {
Person p1 = new Person(1, "first");
Person p2 = p1;//把p1的引用赋值给p2
System.out.println("p2.name before:"+p2.getName());
p1.setName("second");
System.out.println("p2.name after:"+p2.getName());
}
}
CloneTest
输出结果为:
p2.name before:first
p2.name after:second
如果在改变p1的值之后不想改变p2的值,应该如何处理呢?这时候需要用到拷贝,拷贝用到的函数为object的clone()方法
深拷贝和浅拷贝
clone()方法:
package tudou.javabasic.clone; /**
* Created by tudou on 2017-02-22.
* 浅拷贝
*/
public class ShallowCopyPerson implements Cloneable {
private int age;
private String name;
private Address address; public ShallowCopyPerson(int age, String name, Address address) {
this.age = age;
this.name = name;
this.address = address;
}
public Object clone() {
try {
return (ShallowCopyPerson)super.clone();
} catch (Exception e) {
e.printStackTrace();
return null;
}
} public Address getAddress() {
return address;
} public void setAddress(Address address) {
this.address = address;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "ShallowCopyPerson{" +
"age=" + age +
", name='" + name + '\'' +
", address=" + address +
'}';
}
}
ShallowCopyPerson
ShallowCopyPerson 类扩展Cloneable接口,重点关注的方法是clone()方法,这里只是简单使用:
public Object clone() {
try {
return (ShallowCopyPerson)super.clone();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
接下来使用ShallowCopyPerson 类,来观察下列代码的运行结果:
//对象浅拷贝
private static void shallowCopyTest() {
Address address = new Address("Henan", "zhoukou");
ShallowCopyPerson shallowCopyPerson = new ShallowCopyPerson(
18,
"tudou",
address
);
ShallowCopyPerson personClone = (ShallowCopyPerson) shallowCopyPerson.clone();
System.out.println("personClone info before:" + personClone.toString());
System.out.println("shallowCopyPerson info before:" + shallowCopyPerson.toString());
//这里改变原 shallowCopyPerson的值
shallowCopyPerson.setName("new tudou");
shallowCopyPerson.setAge(19);
//改变address的地址值
address.setCity("fj");
address.setProvince("fz");
shallowCopyPerson.setAddress(address);
System.out.println("personClone info after:" + personClone.toString());
System.out.println("shallowCopyPerson info before:" + shallowCopyPerson.toString());
}
shallowCopyTest
结果如下:
ersonClone info before:ShallowCopyPerson{age=18, name='tudou', address=Address{province='Henan', city='zhoukou'}}
shallowCopyPerson info before:ShallowCopyPerson{age=18, name='tudou', address=Address{province='Henan', city='zhoukou'}}
personClone info after:ShallowCopyPerson{age=18, name='tudou', address=Address{province='fz', city='fj'}}
shallowCopyPerson info before:ShallowCopyPerson{age=19, name='new tudou', address=Address{province='fz', city='fj'}}
package tudou.javabasic.clone; /**
* Created by tudou on 2017-02-22.
* 深拷贝
*/
public class DeepCopyPerson implements Cloneable {
private int age;
private String name;
private Address address; public DeepCopyPerson(int age, String name, Address address) {
this.age = age;
this.name = name;
this.address = address;
}
public Object clone() {
try {
return (DeepCopyPerson)super.clone();
} catch (Exception e) {
e.printStackTrace();
return null;
}
} public Address getAddress() {
return address;
} public void setAddress(String province, String city) {
address = new Address(province,city);
address.setCity(city);
address.setProvince(province);
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "ShallowCopyPerson{" +
"age=" + age +
", name='" + name + '\'' +
", address=" + address +
'}';
}
}
DeepCopyPerson
运行下面代码:
//对象深拷贝
private static void deepCopyTest() {
Address address = new Address("Henan", "zhoukou");
DeepCopyPerson deepCopyPerson = new DeepCopyPerson(
18,
"tudou",
address
);
DeepCopyPerson personClone = (DeepCopyPerson) deepCopyPerson.clone();
System.out.println("personClone info before:" + personClone.toString());
//这里改变原 shallowCopyPerson的值
deepCopyPerson.setName("new tudou");
deepCopyPerson.setAge(19);
//改变address的地址值
// address.setCity("zhengzhou");
deepCopyPerson.setAddress("fj","fz");
System.out.println("personClone info after:" + personClone.toString());
}
deepCopyTest
结果如下:
personClone info before:ShallowCopyPerson{age=18, name='tudou', address=Address{province='Henan', city='zhoukou'}}
personClone info after:ShallowCopyPerson{age=18, name='tudou', address=Address{province='Henan', city='zhoukou'}}
可以看到这里值完全没有改变。这里实现的深拷贝只是简单的来实现效果,不做效率方面的考虑。
总结
对象赋值:把一个对象的地址复制给另一个对象,二者都指向堆栈中的地址。所以一个对象中的值变了,另一个也会变。
浅拷贝:对于基本类型,克隆对象和原对象相互独立,没有影响,对于引用类型,复制的还是地址值,所以一个改变了,另一个也会改变。
深拷贝:原对象和克隆对象相互独立,不受影响。
java对象拷贝和复制的更多相关文章
- JAVA 对象拷贝
1.java里的clone分为: A:浅复制(浅克隆): 浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. b:深复制(深克隆):深复制把要复制的对象所引用的对象都复制了一遍. Java中对 ...
- java对象实现深复制的方法
p2 = (Person)org.apache.commons.lang3.ObjectUtils.cloneBean(p); Person p2 = new Person(); p2 = (Pers ...
- Java对象拷贝备忘
列举 //cglib net.sf.cglib.beans.BeanCopier.create net.sf.cglib.beans.BeanCopier.copy //spring-beans or ...
- java 对象之间的复制
package com.jy.demo.web; import java.util.Date; public class People { private String name;//姓名 priva ...
- Java 对象拷贝方式
(1)BeanUtils.cloneBean()使用: http://www.cnblogs.com/fervour/archive/2009/12/18/1627868.html package c ...
- Java Object 对象拷贝
Java Object 对象拷贝 @author ixenos JAVA 对象拷贝 Java里的clone分为: 1.浅拷贝:浅复制仅仅复制所考虑的对象,而不复制它所引用的对象,Object类里的c ...
- 通过与C++程序对比,彻底搞清楚JAVA的对象拷贝
目录 一.背景 二.JAVA对象拷贝的实现 2.1 浅拷贝 2.2 深拷贝的实现方法一 2.3 深拷贝的实现方法二 2.3.1 C++拷贝构造函数 2.3.2 C++源码 2.3.3 JAVA通过拷贝 ...
- Java对象和集合的拷贝/克隆/复制
昨天同事遇到了一个奇怪的问题,他需要将一个JavaBean拷贝一份,然后对新创建的Bean进行操作.但是他对新的Bean操作后,会影响旧的Bean的值.当听到这个问题的时候,我第一反应就是他的拷贝方法 ...
- Java提高篇——对象克隆(复制)
假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short, ...
随机推荐
- GooglePlay - 文件上传限制的扩展
前言 Google Play应用商店在上传限制100MB大小,超过该大小的应用必须将超过部分以扩展文件的形式进行上传处理. 总共可上传2个扩展文件,每个最大文件可为2GB,同时obb文件格式可自选. ...
- win10 uwp 截图 获取屏幕显示界面保存图片
本文主要讲如何保存我们的屏幕显示的,保存为图片,也就是截图,截我们应用显示的. UWP有一个功能,可以截图,RenderTargetBitmap 我们首先写一个Grid,我们需要给他名字,我这里给他S ...
- 深入浅出:JavaScript作用域链
1. 什么是作用域 任何程序设计语言都有作用域的概念,简单的说,作用域就是变量的作用范围. 2. 变量的分类和变量作用域的分类 在JavaScript中,变量分为全局变量和局部变量,与此相对应的,变量 ...
- (转)JVM性能调优之生成堆的dump文件
转自:http://blog.csdn.net/lifuxiangcaohui/article/details/37992725 最近因项目存在内存泄漏,故进行大规模的JVM性能调优 , 现把经验做一 ...
- ASP.NET没有魔法——ASP.NET MVC使用Area开发一个管理模块
之前的My Blog提供了列表的展示和文章显示功能,但是所有数据仍然只能通过数据库录入,为了完成最初的角色“作者”的用例,本章将介绍如何使用“Area”实现My Blog的管理功能. 根据功能分离代码 ...
- R学习笔记 第四篇:函数,分支和循环
变量用于临时存储数据,而函数用于操作数据,实现代码的重复使用.在R中,函数只是另一种数据类型的变量,可以被分配,操作,甚至把函数作为参数传递给其他函数.分支控制和循环控制,和通用编程语言的风格很相似, ...
- JPA的一对多映射(双向)关联
实体Customer:用户. 实体Order:订单. Customer和Order是一对多关系.那么在JPA中,如何表示一对多的双向关联呢? JPA使用@OneToMany和@ManyToOne来标识 ...
- 《Spark Python API 官方文档中文版》 之 pyspark.sql (一)
摘要:在Spark开发中,由于需要用Python实现,发现API与Scala的略有不同,而Python API的中文资料相对很少.每次去查英文版API的说明相对比较慢,还是中文版比较容易get到所需, ...
- poj2689Prime Distance(大区间筛素数)
Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19635 Accepted: 5273 D ...
- 50 years, 50 colors
50 years, 50 colors Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...