浅拷贝和深拷贝

浅拷贝:

package algorithm;

import java.util.ArrayList;

public class ShallowCopy implements Cloneable{
	private String name;
	private ArrayList<String> list = new ArrayList<String>();
	public void printName(){
		System.out.println(this.name);
	}
	public void setName(String name) {
        this.name = name;
    }
	public void addListValue(String value){
		this.list.add(value);
	}
	public void printlnList() {
        System.out.println(this.list);
    }
	public ShallowCopy() {
		System.out.println("shallow copy test");
	}
	/**
	 * 
	 * 浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),
	 * 而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,
	 * 而且拷贝对象包含的引用指向的所有对象。
	 * 
	 */
	@Override
	protected ShallowCopy clone() throws CloneNotSupportedException {
		return (ShallowCopy) super.clone();
	}
	
	public static void main(String[] args) throws CloneNotSupportedException {
		ShallowCopy shallow = new ShallowCopy();
        shallow.setName("yhx");
        shallow.addListValue("Java");
        
        shallow.printName();
        shallow.printlnList();
        
        ShallowCopy shallowCopy = shallow.clone(); // 克隆
        // 打印出两个对象的地址
        System.out.println(shallow);
        System.out.println(shallowCopy);
        
        shallowCopy.addListValue("Python");
        
        shallowCopy.printlnList(); 
        shallowCopy.printName(); 
        
        shallowCopy.setName("hello");
        
        shallow.printName(); // 输出 yhx
        shallowCopy.printName();
        shallow.printlnList(); // // 输出 Java,Python
        
        /**
         * 从结果中我们可以看到
			拷贝时候虽然创建了新的对象,但是并没有调用构造方法
			对象中的引用对象并没有拷贝,引用的地址还是和原对象一致
			基本类型或者 String 默认会拷贝
			像这种只拷贝了对象本身,而对象中引用数据类型没有被拷贝的拷贝方式,叫做浅拷贝。
			浅拷贝往往存在一定的风险,因为引用对象的地址拷贝前后一致,所以对象的值很容易被更改,不安全。
         */
	}
}


深拷贝:

①:

package algorithm;

import java.util.ArrayList;

public class DeepCopy implements Cloneable{
	private String name;
    private ArrayList<String> list = new ArrayList<>();
    public void printlnName() {
        System.out.println(this.name);
    }
    public void setName(String name) {
        this.name = name;
    }
    public void addListValue(String value) {
        this.list.add(value);
    }
    public void printlnList() {
        System.out.println(this.list);
    }
    public DeepCopy() {
        System.out.println("deep copy test");
    }
    @Override
    protected DeepCopy clone() throws CloneNotSupportedException {
    	DeepCopy clone = (DeepCopy) super.clone();
        clone.list = (ArrayList<String>) this.list.clone();
        return clone;
    }
    public static void main(String[] args) throws CloneNotSupportedException {
    	DeepCopy deep = new DeepCopy();
        deep.setName("yhx");
        deep.addListValue("Java");
        deep.printlnName(); 
        deep.printlnList(); 
        DeepCopy deepCopy = deep.clone(); // 克隆
     // 打印出两个对象的地址
        System.out.println(deep);
        System.out.println(deepCopy);
        deepCopy.printlnList();
        deepCopy.addListValue("Python");
        deepCopy.printlnList();
        deepCopy.printlnName();
        deepCopy.setName("hello");
        deep.printlnName();
        deep.printlnList();
        //如果字段上有 final 修饰,就不能实现 clone 方法了,因为 final 变量不能再次被赋值。
	}
}


②串行化深拷贝:

package algorithm;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.io.Serializable;

public class DeepCopyBySeriablizable{
	//串行化很耗时,在一些框架中,我们便可以感受到,它们往往将对象进行串行化后进行传递,耗时较多。
	public static void main(String[] args) 
			throws OptionalDataException, ClassNotFoundException, IOException {
		long t1 = System.currentTimeMillis();
        Professor2 p = new Professor2("wangwu", 50);
        Student2 s1 = new Student2("zhangsan", 18, p);
        Student2 s2 = (Student2) s1.deepClone();
        s2.p.name = "lisi";
        s2.p.age = 30;
        System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // 学生1的教授不改变。
        System.out.println("name=" + s2.p.name + "," + "age=" + s2.p.age);
        long t2 = System.currentTimeMillis();
        System.out.println(t2-t1);
	}
}
class Professor2 implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    String name;
    int age;
 
    Professor2(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
 
class Student2 implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    String name;// 常量对象。
    int age;
    Professor2 p;// 学生1和学生2的引用值都是一样的。
 
    Student2(String name, int age, Professor2 p) {
        this.name = name;
        this.age = age;
        this.p = p;
    }
 
    public Object deepClone() throws IOException, OptionalDataException,
            ClassNotFoundException {
        // 将对象写到流里
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(bo);
        oo.writeObject(this);
        // 从流里读出来
        ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
        ObjectInputStream oi = new ObjectInputStream(bi);
        return (oi.readObject());
    }
 
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值