java 对象值拷贝_Java 值传递与对象拷贝

setter/getter

new 新对象后用 set/get 方法设置属性

浅克隆

被复制的类需要实现Clonenable接口(不实现的话在调用 clone 方法会抛出 CloneNotSupportedException 异常), 该接口为标记接口(不含任何方法)

覆盖clone() 方法,访问修饰符设为 public。方法中调用 super.clone() 方法得到需要的复制对象 class Address

{

private String address;

public String getAddress()

{

return address;

}

public void setAddress(String address)

{

this.address = address;

}

}

class Student implements Cloneable

{

private int number;

private Address addr;

public Address getAddr()

{

return addr;

}

public void setAddr(Address addr)

{

this.addr = addr;

}

public int getNumber()

{

return number;

}

public void setNumber(int number)

{

this.number = number;

}

@Override

public Object clone()

{

Student stu = null;

try

{

stu = (Student) super.clone(); //浅复制

}

catch (CloneNotSupportedException e)

{

e.printStackTrace();

}

return stu;

}

}

public class Test

{

public static void main(String args[])

{

Address addr = new Address();

addr.setAddress("杭州市");

Student stu1 = new Student();

stu1.setNumber(123);

stu1.setAddr(addr);

Student stu2 = (Student) stu1.clone();

System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAddress());

System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAddress());

stu2.setNumber(124);

addr.setAddress("西湖区");

System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAddress());

System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAddress());

}

}

/*

输出

学生1:123,地址:杭州市

学生2:123,地址:杭州市

学生1:123,地址:西湖区

学生2:124,地址:西湖区

*/

通过浅克隆获得新对象,其基本数据类型成员变量得到了复制,修改后不影响原对象

若变量为引用数据类型,则只复制地址引用,还是指向相同地址,修改时会相互影响

若变量为 String 类型,则拷贝其地址引用。但是在修改时,它会从字符串池中重新生成一个新的字符串,原有字符串对象保持不变

深克隆

浅复制只是复制了addr 变量的引用,并没有真正的开辟另一块空间,将值复制后再将引用返回给新对象

为了达到真正的复制对象,而不是纯粹引用复制。我们需要将 Address 类可复制化,并且修改 clone 方法,代码如下: class Address implements Cloneable

{

private String address;

public String getAddress()

{

return address;

}

public void setAddress(String address)

{

this.address = address;

}

@Override

public Object clone()//Address 类可复制化

{

Address addr = null;

try

{

addr = (Address) super.clone();

}

catch (CloneNotSupportedException e)

{

e.printStackTrace();

}

return addr;

}

}

class Student implements Cloneable

{

private int number;

private Address addr;

public Address getAddr()

{

return addr;

}

public void setAddr(Address addr)

{

this.addr = addr;

}

public int getNumber()

{

return number;

}

public void setNumber(int number)

{

this.number = number;

}

@Override

public Object clone()

{

Student stu = null;

try

{

stu = (Student) super.clone(); //浅复制

}

catch (CloneNotSupportedException e)

{

e.printStackTrace();

}

stu.addr = (Address) addr.clone(); //引用数据类型变量深复制

return stu;

}

}

public class Test

{

public static void main(String args[])

{

Address addr = new Address();

addr.setAddress("杭州市");

Student stu1 = new Student();

stu1.setNumber(123);

stu1.setAddr(addr);

Student stu2 = (Student) stu1.clone();

System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAddress());

System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAddress());

stu2.setNumber(124);

addr.setAddress("西湖区");

System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAddress());

System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAddress());

}

}

/*

输出

学生1:123,地址:杭州市

学生2:123,地址:杭州市

学生1:123,地址:西湖区

学生2:124,地址:杭州市

*/

工具类

org.apache.commons 组件 BeanUtils 和 PropertyUtils,静态方法 copyProperties(Object o1,Object o2)

序列化

序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作 class Professor implements Serializable

{

String name;

int age;

Professor(String name, int age)

{

this.name = name;

this.age = age;

}

}

class Student implements Serializable

{

String name;//常量对象

int age;

Professor p;//引用数据类型

Student(String name, int age, Professor p)

{

this.name = name;

this.age = age;

this.p = p;

}

//深克隆

public Object deepClone() throws IOException, 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());

}

}

public class Test

{

public static void main(String[] args) throws IOException, ClassNotFoundException

{

Professor p = new Professor("wangwu", 50);

Student s1 = new Student("zhangsan", 18, p);

Student s2 = (Student) s1.deepClone();

s2.p.name = "lisi";

s2.p.age = 30;

System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age);

//学生1的教授不改变

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值