代码说明java中的赋值、浅拷贝、深拷贝

Student类:

public class Student implements Cloneable,Serializable{
	private static final long serialVersionUID = 4736229991747913221L;
	private int age;
	private Car car;

	//篇幅原因省略构造/get/set方法

	@Override
	protected Student clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return (Student) super.clone();
	}
}

Car类:

public class Car implements Cloneable,Serializable{
	private static final long serialVersionUID = 1705363073258599641L;
	private int price;
    
    //篇幅原因省略构造/get/set方法
}

 

一、赋值


public void test1() {
	Student zhang=new Student();
	zhang.setAge(5);
	Student wang=new Student();
	System.out.println(zhang+" "+wang);
	wang=zhang;
	System.out.println(zhang+" "+wang);
	System.out.println(wang.getAge());
	wang.setAge(6);
	System.out.println(zhang.getAge());
}

运行结果:

clone.Student@4459eb14 clone.Student@5a2e4553
clone.Student@4459eb14 clone.Student@4459eb14
5
6

引用类型进行赋值时,赋的值是引用的值,wang=zhang;即将zhang的地址赋值给wang,此时两者指向同一块内存。

二、浅克隆

public void test2() throws CloneNotSupportedException{
	Student zhang=new Student(5, new Car(10000));
	Student wang=zhang.clone();
	System.out.println(zhang+" "+wang);
	System.out.println(wang.getAge()+"  "+wang.getCar().getPrice());
	//改变wang中的普通类型
	wang.setAge(6);
	//改变wang中的引用类型
	wang.getCar().setPrice(200000);
	//zhang中的普通类型不变,引用类型被改变
	System.out.println(zhang.getAge()+"  "+zhang.getCar().getPrice());
}

运行结果:

clone.Student@4459eb14 clone.Student@5a2e4553
5  10000
5  200000

实现Cloneable接口并重写clone方法(见Student类)进行浅拷贝,该方法使wang拥有与zhang不同的引用,但其中的引用类型Car依旧指向同一地址。

三、深克隆

实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆

public void test3() throws Exception{
	Student zhang=new Student(5, new Car(10000));
	Student wang=MyUtil.clone(zhang);
	System.out.println(zhang+" "+wang);
	System.out.println(wang.getAge()+"  "+wang.getCar().getPrice());
	//改变wang中的普通类型
	wang.setAge(6);
	//改变wang中的引用类型
	wang.getCar().setPrice(200000);
	//zhang中的普通类型不变,引用类型被改变
	System.out.println(zhang.getAge()+"  "+zhang.getCar().getPrice());
}

MyUtil类: 

public class MyUtil {
    private MyUtil() {
        throw new AssertionError();
    }
    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T clone(T obj) throws Exception {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bout);
        oos.writeObject(obj);

        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bin);
        return (T) ois.readObject();
    }
}

运行结果:

clone.Student@6d5380c2 clone.Student@3d012ddd
5  10000
5  10000

 该方法使wang拥有与zhang不同的引用,其中的引用类型Car也指向不同地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值