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, ...
随机推荐
- python 输出语句的写法
总结: 1.类似于C语言的格式化输出,先写转换符,再写待转换的对象. 2.与C语言不同的是,转换符和待转换的对象之间,不能用逗号分隔. #!/usr/bin/env python #print dig ...
- 初学者易上手的SSH-struts2 02Action获取表单数据-通配符
在上一章中,我们已经搭建好了struts2的一个开发环境,那么这一章就来做一个简单的登录功能,以及介绍和使用struts2里面一个重要的东西-通配符. 第一步,在WebContent下面新建一个log ...
- 【学习】js学习笔记:数组(二)
二维数组 例子:矩形反转: <script> var arr=[[1,1,1,1,1],[2,2,2,2,2],[3,3,3,3,3],[4,4,4,4,4],[5,5,5,5,5]]; ...
- Extjs6(七)——增删查改之删除
本文基于ext-6.0.0 页面就是前面写的那个,有不清楚的可以看一下前面写页面那篇. 一.在toolbar加一个删除按钮 { text:'删除', iconCls:'x-fa fa-times', ...
- 二:Linux 的基本命令、VI编辑器、Linux中软件安装
Linux 的基本命令 1. 文件操作 a) Windows 是多根的文件系统,物理上是 1 到多块硬盘,逻辑上分为 C.D.E--盘, 每个盘都是一棵树.Linux 是单根的文件系统,不分 CDE ...
- Ajax笔记 XHR XMLHttpRequest
XMLHttpRequest xhr XmlHttpRequest var request ; if(Windows.XMLHttpRequest) { request ...
- 【转】S3C2440与SDRAM NorFlash NandFlash连线分析
一.SDRAM(HY57V561620F)连线分析 1. S3C2440 有27根地址线ADDR[26:0],8根片选信号ngcs0-ngcs7,对应bank0-bank7,当访问bankx 的地址 ...
- ELK系列~对fluentd参数的理解
这段时候一直在研究ELK框架,主要集成在对fluentd和nxlog的研究上,国内文章不多,主要看了一下官方的API,配合自己的理解,总结了一下,希望可以帮到刚入行的朋友们! Fluentd(日志收集 ...
- 用 Smali 手写一个可运行的 HelloWorld!!!
一.前言 Android 的 App 实际上并不是运行在 Java 虚拟机中,而是运行在 Dalvik 虚拟机中.Dalvik 虚拟机对 Java 虚拟机做了一些额外的优化,让它更适用于移动设备.而 ...
- LeetCode 628. Maximum Product of Three Numbers (最大三数乘积)
Given an integer array, find three numbers whose product is maximum and output the maximum product. ...