Java中的堆与栈之克隆篇

365365bet官网 2025-07-24 09:21:20 admin 3057 288
Java中的堆与栈之克隆篇

对于深克隆而言,如果类有许多引用类型的域,那么重写clone方法依次复制各个域是非常麻烦的。如果引用类型的域也是由引用类型组成的,则应该考虑使用序列化的方法实现深克隆。

序列化可以将任意对象写入到流中。根据流的类型不同,可以将对象写入到文件中。也可以将对象写入到字节数组中。克隆对象时一般不需要先进行保存,因此将使用字节数组。在写入完成后,再将其读出就可以实现克隆。使用序列化可以不用考虑引用类型的域,编写clone()方法相对简单,但是要求引用类型也实现Serializable接口。

注:如果使用了API中的类并且该类并没有实现Serializable接口,则该域需要使用transient修饰。

代码如下:

package com.trouble.clone;

import java.io.Serializable;

public class Address implements Serializable {

private static final long serialVersionUID = 1L;

private String state;

private String province;

private String city;

public Address(String state, String province, String city) {

this.state = state;

this.province = province;

this.city = city;

}

public String getState() {

return state;

}

public void setState(String state) {

this.state = state;

}

public String getProvince() {

return province;

}

public void setProvince(String province) {

this.province = province;

}

public String getCity() {

return city;

}

public void setCity(String city) {

this.city = city;

}

@Override

public String toString() {

// TODO Auto-generated method stub

StringBuilder sb = new StringBuilder();

sb.append("国家:" + state + ",");

sb.append("省:" + province + ",");

sb.append("市:" + city);

return sb.toString();

}

}

package com.trouble.clone;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;

public class Employee implements Serializable, Cloneable {

private static final long serialVersionUID = 1L;

private String name;

private int age;

private Address address;

public Employee(String name, int age, Address address) {

this.name = name;

this.age = age;

this.address = address;

}

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;

}

public Address getAddress() {

return address;

}

public void setAddress(Address address) {

this.address = address;

}

@Override

public String toString() {

// TODO Auto-generated method stub

StringBuilder sb = new StringBuilder();

sb.append("姓名:" + name + ",");

sb.append("年龄:" + age + "\n");

sb.append("地址:" + address);

return sb.toString();

}

@Override

protected Employee clone() {

Employee employee = null;

ByteArrayOutputStream baos = new ByteArrayOutputStream();

try {

ObjectOutputStream oos = new ObjectOutputStream(baos);

oos.writeObject(this);

oos.close();

} catch (IOException e) {

e.printStackTrace();

}

ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

try {

ObjectInputStream ois = new ObjectInputStream(bais);

employee = (Employee) ois.readObject();

ois.close();

} catch (IOException | ClassNotFoundException e) {

e.printStackTrace();

}

return employee;

}

}

package com.trouble.clone;

public class Test {

public static void main(String[] args){

Address address = new Address("中国","吉林","长春");

Employee employee1 = new Employee("明月科技",12,address);

System.out.println(employee1);

Employee employee2 = employee1.clone();

System.out.println(employee2);

employee2.setAge(14);

employee2.getAddress().setProvince("四川");

employee2.getAddress().setCity("成都");

System.out.println(employee1);

System.out.println(employee2);

}

}

注:首先,对于任何一个序列化的对象,都要求其实现Serializable接口。其次,如果该类的域中有引用类型,则要求该引用类型也实现Serializable接口,以此类推,最后序列化方式实现克隆会比直接克隆各个引用类型域慢,这一点在效率优先时要考虑。

相关推荐

足球365官网是哪个 剑网3阴阳两界由我行奇遇触发条件 坐骑霸红尘获取攻略

剑网3阴阳两界由我行奇遇触发条件 坐骑霸红尘获取攻略

📅 07-17 👁️ 6353
足球365官网是哪个 淘口令在手淘无法弹出?当心被永久关闭淘口令功能

淘口令在手淘无法弹出?当心被永久关闭淘口令功能

📅 07-21 👁️ 2893
365BET 微店在哪里可以找到

微店在哪里可以找到

📅 07-02 👁️ 3747