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;
}
}
View Code

 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);
    }

}
View Code

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();
}

}
View Code

 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(); 
}

}
View Code

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);
    }

}
View Code

技术图片

 

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

总之深浅克隆都会在堆中新分配一块区域,区别在于对象属性引用的对象是否需要进行克隆(递归性的)。

三、深克隆

 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;
    }
}
View Code

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(); 
}


}
View Code

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);

    }
}
View Code

技术图片

 

以上是关于java 浅克隆 深克隆的主要内容,如果未能解决你的问题,请参考以下文章

Java浅克隆和深克隆

java浅克隆与深克隆

java对象的浅克隆和深克隆

Git 浅克隆

Java深拷贝和浅拷贝(深克隆和浅克隆)

Java学习笔记——设计模式之六.原型模式(浅克隆和深克隆)