java 浅克隆 深克隆
Posted helloworld2019
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 浅克隆 深克隆相关的知识,希望对你有一定的参考价值。
对象的克隆是java的一项高级技术,他可以根据给定的对象,获得与其完全相同的另一个对象。
一、常见的错误:
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(17); System.out.println(employee1); System.out.println("克隆后"); Employee employee2=employee1; employee2.setName("王二小"); employee2.setAge(19); 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 浅克隆 深克隆的主要内容,如果未能解决你的问题,请参考以下文章