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(). 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多 ...
随机推荐
- mssql sqlserver 下文分享一种新颖的字符串截取方法
原文地址:http://www.maomao365.com/?p=7307 摘要: 以前分割字符串时,都使用类似split函数的方式处理,下文分享一种对有规律的字符串的分隔方式, 即:1. ...
- win10监听剪切板变化
一.第一步导入api #region [DllImport("user32.dll")] public static extern bool AddClipboardFormatL ...
- Python的变量以及类型
1.程序是用来处理数据的,变量就是用来存储数据的 num1 = 100 2.为了更充分的利用内存空间以及更有效率的管理内存,变量是有不同的类型 3.怎样知道一个变量的类型呢? 3.1 在python ...
- Windows Server 2016-WinSer 2016标准版与数据中心版的区别
今天在整理文章的时候看到有读者问到他现在的测试环境是用的Windows Server 2016标准版,和我现阶段系列文章的环境是否有区别. 其实针对Windows Server 2016 Active ...
- Java教程01-基础语法
目录 1. 基本概念 1.1. 环境变量 Path环境变量的作用->寻找命令 classpath变量的作用->寻找类文件 1.2. JDK里面有什么? 1.3. 什么是JRE? 2. Ja ...
- 微信小程序跳转微信小程序新增配置项目 navigateToMiniProgramAppIdList
每个小程序可跳转的其他小程序数量限制为不超过 10 个 从 2.4.0 版本以及指定日期(具体待定)开始,开发者提交新版小程序代码时,如使用了跳转其他小程序功能,则需要在代码配置中声明将要跳转的小程序 ...
- python 管道、数据共享、进程池
一.管道(Pipe)(了解) (详情参考:https://www.cnblogs.com/clschao/articles/9629392.html) 进程间通信(IPC)方式二:管道(不推荐使用,了 ...
- C. Magic Ship cf 二分
C. Magic Ship time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- 利用nginx搭建小型的文件服务器
PS内的文件如果需要共享给其他计算机下载,可以选择ftp的方式,优点是操作性很高,修改删除下载等等都可以,但是速度略慢. 如果仅仅是将VPS作为文件中转站,可以尝试用Nginx架设一个简单的文件服务器 ...
- JAVA序列化和反序列化XML
package com.lss.utils; import java.beans.XMLDecoder; import java.beans.XMLEncoder; import java.io.Bu ...