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(). 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多 ...
随机推荐
- C#发布和调试WebService
一.编写并发布WebService服务 1.新建空web应用程序
- Java中的生产消费者问题
package day190109; import java.util.LinkedList; import java.util.Queue; import java.util.Random; pub ...
- Jenkins的构建编号和一个有趣的bug
什么是构建编号 jenkins每个job的每一次构建都有一个属于自己独立的构建编号,每一次的构建结果(成功或失败)所使用的编号都是不相同的. 正确的构建编号:每个job的每次构建结果使用不相同的构建编 ...
- Python: 遍历
======================遍历列表========================# 直接遍历list: for elem in list: pass # 通过索引获取 for i ...
- XSS 漏洞原理及防御方法
XSS跨站脚本攻击:两种情况.一种通过外部输入然后直接在浏览器端触发,即反射型XSS:还有一种则是先把利用代码保存在数据库或文件中,当web程序读取利用代码并输出在页面上时触发漏洞,即存储型XSS.D ...
- Linux中“!"的神奇用法
前言 实际上,不起眼的“!”在linux中有着很多让你惊叹的妙用.本文就来细数那些“!”的神奇用法. 执行上一条命令 例如,在执行完上面一条命令后,可以使用下面的方式再次执行上一条命令: $ wher ...
- (转)Spring Boot (十九):使用 Spring Boot Actuator 监控应用
http://www.ityouknow.com/springboot/2018/02/06/spring-boot-actuator.html 微服务的特点决定了功能模块的部署是分布式的,大部分功能 ...
- JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- [CQOI2018]九连环
嘟嘟嘟 对于这种找规律的题,我向来是不会的. 通过大佬们的各种打表找规律.神奇dp等方法,我们得到了答案就是\(\lfloor \frac{2 ^ {n + 1}}{3} \rfloor\). 高精是 ...
- 转://Oracle 高可用技术与云基础架构
众所周知Oracle云基础架构已经在越来越多的行业里应用.大家了解云基础架构是如何演进的嘛?可能有人会说Oracle高可用技术是组成云架构的基础,那它们的关系是怎么样的?大家又了解Oracle高可用技 ...