java 浅克隆 深克隆
对象的克隆是java的一项高级技术,他可以根据给定的对象,获得与其完全相同的另一个对象。
1.浅克隆主要是复制对象的值
2.深克隆:当类存在聚合关系的时候,克隆就必须考虑聚合对象的克隆,可以复制引用类型的字段。
一、常见的错误:
Employee 类
package text1;
public class Employee {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private int age;
public String toString(){
return "姓名"+name+"年龄: "+age;
}
}
Test
package text1;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("克隆前");
Employee employee1=new Employee();
employee1.setName("张三丰");
employee1.setAge();
System.out.println(employee1);
System.out.println("克隆后");
Employee employee2=employee1;
employee2.setName("王二小");
employee2.setAge();
System.out.println("输出员工一的信息");
System.out.println(employee1);
System.out.println("输出第二个员工的信息");
System.out.println(employee2);
}
}
java中,对于基本类型可以使用 "="来克隆,此时两个变量除了相等时没有任何关系的。
而在引用类型却不能简单地使用“=”进行克隆,这与java内存空间的使用有关。java将内存分为两块,堆和栈。
在栈中保存基本类型和引用变量,堆中保存对象。对于引用变量而言,使用“=”将修改引用,而不是复制堆中的对象,此时两个引用
变量将指向同一个对象,因此,如果一个变量对其进行修改将改变另一个变量。
说白了就是指向同一个对象。。。假克隆
二、java对象的浅克隆
如果对象是基本类型,则采用浅克隆就行,如果对象的成员变量包括可引用类型,需要深克隆。
***如果引用类型不变,String类的对象,则不需要深克隆
Address类;
public class Address {
private String state;
private String province;
private String city;
public void setState(String state) {
this.state = state;
}
public void setProvince(String province) {
this.province = province;
}
public void setCity(String city) {
this.city = city;
}
public Address(String state,String province,String city){
this.state=state;
this.province=province;
this.city=city;
}
//@Override
public String toString(){
StringBuilder sb=new StringBuilder();
sb.append("国家 :"+state+",\n");
sb.append("省 "+province+",\n");
sb.append("市 "+city);
return sb.toString();
}
}
Employee类:
package text6;
public class Employee implements Cloneable{
private String name;
private int age;
private Address address;
public Address getAddress() {
return address;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(Address address) {
this.address = address;
}
public Employee(String name,int age,Address address){
this.name=name;
this.age=age;
this.address=address;
}
public Employee clone(){
Employee employee=null;
try{
employee=(Employee)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return employee;
}
public String toString(){
StringBuilder sb=new StringBuilder();
sb.append("姓名 "+name+",\n");
sb.append("年龄 "+age+",\n");
sb.append("地址 \n"+address);
return sb.toString();
}
}
Test
package text6;
public class Text {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("克隆之前");
Address address = new Address("中国", "吉林", "长春");
Employee employee1 = new Employee("张三丰", 30, address);
System.out.println(employee1);
System.out.println("克隆后");
Employee employee2 = employee1.clone();
employee2.getAddress().setState("中国"); // getaddres没有定义
employee2.getAddress().setCity("成都");
employee2.getAddress().setProvince("四川");
System.out.println(employee1);
System.out.println(employee2);
}
}

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
总之深浅克隆都会在堆中新分配一块区域,区别在于对象属性引用的对象是否需要进行克隆(递归性的)。
三、深克隆
Address类
package text7; /*引用对象不可变的不必进行深克隆
* 如果类成员变量包括可以引用的类型
则在克隆时候就需要进行深克隆
*/
public class Address implements Cloneable {
private String state;
private String province;
private String city; public void setState(String state) {
this.state = state;
} public void setProvince(String province) {
this.province = province;
} public void setCity(String city) {
this.city = city;
} public Address(String state, String province, String city) {
this.state = state;
this.province = province;
this.city = city;
} // @Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("国家 :" + state + ",");
sb.append("省 " + province + ",");
sb.append("市 " + city);
return sb.toString();
} protected Address clone() {
Address address = null;
try {
address = (Address) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return address;
}
}
Employee类:
package text7;
public class Employee implements Cloneable{
private String name;
private int age;
private Address address;
public Address getAddress() {
return address;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(Address address) {
this.address = address;
}
public Employee(String name,int age,Address address){
this.name=name;
this.age=age;
this.address=address;
}
public Employee clone(){
Employee employee=null;
try{
employee=(Employee)super.clone();
employee.address=address.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return employee;
}
public String toString(){
StringBuilder sb=new StringBuilder();
sb.append("姓名 "+name+",\n");
sb.append("年龄 "+age+",\n");
sb.append("地址 \n"+address);
return sb.toString();
}
}
Test
package text7;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("克隆前");
Address address = new Address("中国", "吉林", "长春");
Employee employee1 = new Employee("张三丰", 30, address);
System.out.println("员工一信息");
System.out.println(employee1);
System.out.println("克隆后");
Employee employee2 = employee1.clone();
employee2.getAddress().setState("中国");
employee2.getAddress().setProvince("四川");
employee2.getAddress().setCity("成都");
employee2.setName("李云龙");
employee2.setAge(24);
System.out.println("员工一信息");
System.out.println(employee1);
System.out.println("员工二信息");
System.out.println(employee2);
}
}

java 浅克隆 深克隆的更多相关文章
- Java克隆--深克隆与浅克隆的区别
克隆,就是复制一个对象的副本,而克隆又分浅克隆和深克隆.浅克隆是指克隆得到的对象基本类型的值改变了,而源对象的值不会变.但如果被克隆对象引用类型的值改变了,那么源对象的值同样会改变,因为引用类型在栈内 ...
- java浅克隆和深克隆,序列化和反序列化实现深克隆(封装序列化和反序列化操作)
本篇博客内容: 一.浅克隆(ShallowClone)和深克隆(DeepClone) 二.序列化和反序列化实现深克隆 三.封装序列化和反序列化操作 ObjectOutputStream + 内存流By ...
- java 浅克隆(浅复制)和深克隆(深复制)
http://www.voidcn.com/blog/u011380813/article/p-6161450.html https://gold.xitu.io/entry/570d89651ea4 ...
- Java实现深克隆的两种方式
序列化和依次克隆各个可变的引用类型都可以实现深克隆,但是序列化的效率并不理想 下面是两种实现深克隆的实例,并且测试类对两种方法进行了对比: 1.重写clone方法使用父类中的clone()方法实现深克 ...
- Java基础--深克隆补充
深克隆文章很多,这里推荐Java提高篇--对象克隆(复制). 以上文章条理清晰,一目了然,但最近在项目中碰到的实际问题是,所要克隆的对象是加上子类父类共计207个,无论用上述两种方式的哪一种,都要一一 ...
- 深入理解Java对象的创建过程:类的初始化与实例化
摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类 ...
- Java对象的克隆和深浅问题
Java实现克隆的方式 Java实现克隆的方式有如下两种, 推荐采用实现Cloneable接口的方式 实现Cloneable接口, 重写clone方法, 调用父类的clone方法 还有另一种方法, 不 ...
- 《practical Java》读书笔记
题记: 花了一周把Peter Haggar的<practical Java>看了遍,有所感悟,年纪大了, 写下笔记,方便日后查看.也希望有缘之人可以看看,做个渺小的指路人. 不足之处还望指 ...
- java 的原型模式和clone
原型模式是一种创建型设计模式,在java中可以直接调用object.clone(). 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多 ...
随机推荐
- [20181015]为什么是3秒.txt
[20181015]为什么是3秒.txt --//以前测试:连接http://blog.itpub.net/267265/viewspace-2144765/=>为什么是12秒.txt.--// ...
- linux c 开发通用结构,框架
转自:http://www.maomao365.com/?p=673 了解其它语言的框架例:java Struts1.Struts2.Hibernate.Mybatis.Ibatis.Spring 等 ...
- 【底层原理】深入理解Cache (下)
得到了我的PC的cache参数如下: L1 Cache : 32KB , 8路组相连,linesize为 64Byte 64个组 L2 Cache:256KB 8路组相连,linesize为 64By ...
- CVE-2012-0158 分析
目录 CVE-2012-0158 分析&利用 1.实验环境 2.下载poc样本 3.调试并找到漏洞触发点 4.分析漏洞触发模块及流程 5.漏洞利用 6.总结 7.参考资料 CVE-2012-0 ...
- 利用fpm制作rpm包
使用fpm制作rpm包 安装如下 [root@web01 ~]# yum install -y gcc zlib zlib-devel wget http://ruby.taobao.org/mirr ...
- Docker 入门到实践(三)Docker 安装
注意:不要在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker. 一.准备工作 系统要求 Docker CE 支持一下版本的 Ubuntu 操作系统 Cosmic 18 ...
- php学习----运算符
PHP 1.运算符 加减乘除与数学运算无异 但PHP的赋值运算符有两种,分别是: (1)"=":把右边表达式的值赋给左边的运算数.它将右边表达式值复制一份,交给左边的运算数.换而言 ...
- JavaScript数据类型之数字类型
引言 JavaScript不区分整数值和浮点数值,全部使用浮点数值表示.当一个数字直接出现在JavaScript程序中,我们称之为数字直接量(numeric litertal).JavaScript支 ...
- Jenkins+Ansible+Gitlab自动化部署三剑客-Jenkins本地搭建
后面需要shell基础,目前没有,等有了,再更
- Linux之系统优化
查看系统版本 [root@luffy- /]# cat /etc/redhat-release CentOS release 6.9 (Final) [root@luffy- /]# uname -m ...