首页 > 代码库 > Java对象的复制方法总结
Java对象的复制方法总结
参考:《Java经典编程》实例054~058,《Java7 入门经典》
1. 使用构造函数复制对象
对象是传址调用,直接通过“=”来进行连接是并没有达到复制对象的目的。下面这样的类可以通过构造函数来复制对象。局限在于,要求生成对象的类的域仅仅是基本类型,没有其他引用类型。如果有引用类型,则新对象仅仅复制了引用类型的副本,他们指向同一个对象,这是浅复制。除非对该引用类型也再次进行构造函数的复制,直到所有复制都针对的是基本类型,这是深复制。
根据《Java7 入门经典》P250页6.8.3节的说法,跟第二类的复杂的克隆相比,构造函数法是复制对象方法的最佳实践。
第一类:域只有基本类型
public class Employee { private String name; private int age; /** * 构造函数复制对象 */ public Employee(Employee employee) { // TODO Auto-generated constructor stub name=employee.getName(); age=employee.getAge(); } /** * 初始化 */ public Employee(String name,int age) { // TODO Auto-generated constructor stub this.name=name; this.age=age; } @Override public String toString() { // TODO Auto-generated method stub return "姓名:"+name+",年龄"+age; } //省略set()和get()函数 }
第二类:域有引用类型Addres address,需要对其也进行构造函数复制
/** * 创建时间:2014年9月8日 下午2:38:13 * 项目名称:Test * @author Cao Yanfeng * @since JDK 1.6.0_21 * 类说明: */ public class Employee { private String name; private int age; private Address address; /** * 初始化 */ public Employee(String name,int age,Address address) { // TODO Auto-generated constructor stub this.name=name; this.age=age; this.address=new Address(address); } /** * 构造函数复制 */ public Employee(Employee employee) { // TODO Auto-generated constructor stub name=employee.getName(); age=employee.getAge(); address=<span style="font-family: Arial, Helvetica, sans-serif;">new Address(</span><span style="font-family: Arial, Helvetica, sans-serif;">employee.getAddress()</span><span style="font-family: Arial, Helvetica, sans-serif;">)</span>; } @Override public String toString() { // TODO Auto-generated method stub return "姓名:"+name+",年龄:"+age+",地址——"+address; } //省略set()和get()函数 } /** * 创建时间:2014年9月8日 下午2:52:18 项目名称:Test * * @author Cao Yanfeng * @since JDK 1.6.0_21 类说明: */ public class Address { private String state; private String province; private String city; /** * 构造函数实现复制 */ public Address(Address address) { // TODO Auto-generated constructor stub state=address.state; province=address.province; city=address.city; } /** * 初始化 */ public Address(String state, String province, String city) { // TODO Auto-generated constructor stub this.state = state; this.province = province; this.city = city; } @Override public String toString() { // TODO Auto-generated method stub StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("国家:" + state + ","); stringBuilder.append("省:" + province + ","); stringBuilder.append("市:" + city); return stringBuilder.toString(); } //省略set()和get()函数 }
2. 对象克隆
克隆的效果和使用构造函数复制对象高度一致,局限在于,要求生成对象的类的域仅仅是基本类型,没有其他引用类型。如果有引用类型,则新对象仅仅复制了引用类型的副本,他们指向同一个对象,并没有对其进行克隆,这是浅克隆。除非对该引用类型也再次进行clone,直到所有clone都针对的是基本类型,这就是深度克隆。注意,所有类都要实现Cloneable接口,并重写clone()方法。
第一类:域只有基本类型
/
** * 创建时间:2014年9月8日 下午2:38:13 项目名称:Test * * @author Cao Yanfeng * @since JDK 1.6.0_21 类说明: */ public class Employee implements Cloneable { private String name; private int age; /** * 初始化 */ public Employee(String name, int age) { // TODO Auto-generated constructor stub this.name = name; this.age = age; } @Override protected Employee clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Employee employee = null; employee = (Employee) super.clone(); return employee; } @Override public String toString() { // TODO Auto-generated method stub // return "姓名:"+name+",年龄:"+age+",地址——"+address; return "姓名:" + name + ",年龄:" + age; } //省略set()和get()函数 }
第二类:域有引用类型Addres address,需要对其也进行clone
/** * 创建时间:2014年9月8日 下午2:38:13 项目名称:Test * * @author Cao Yanfeng * @since JDK 1.6.0_21 类说明: */ public class Employee implements Cloneable { private String name; private int age; private Address address; /** * */ public Employee(String name, int age,Address address) { // TODO Auto-generated constructor stub this.name = name; this.age = age; this.address=address; } // @Override protected Employee clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Employee employee = null; employee = (Employee) super.clone(); employee.address=address.clone(); return employee; } @Override public String toString() { // TODO Auto-generated method stub return "姓名:"+name+",年龄:"+age+",地址——"+address; } //省略set()和get()函数 } /** * 创建时间:2014年9月8日 下午2:52:18 项目名称:Test * * @author Cao Yanfeng * @since JDK 1.6.0_21 类说明: */ public class Address implements Cloneable{ private String state; private String province; private String city; /** * 初始化 */ public Address(String state, String province, String city) { // TODO Auto-generated constructor stub this.state = state; this.province = province; this.city = city; } @Override protected Address clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Address address=null; address=(Address)super.clone(); return address; } @Override public String toString() { // TODO Auto-generated method stub StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("国家:" + state + ","); stringBuilder.append("省:" + province + ","); stringBuilder.append("市:" + city); return stringBuilder.toString(); } //省略set()和get()函数 }
3. 对象序列化
对象序列化即把待复制的对象从内存写到本地文件中,然后再从本地文件读到出内存中并赋给新的引用。对象序列号实现了深度克隆。注意,待序列化化的对象要实现Serializable接口,域中如果有引用类型,也要实现Serializable接口,否则序列化出错。
/** * 创建时间:2014年9月8日 下午2:36:34 * 项目名称:Test * @author Cao Yanfeng * @since JDK 1.6.0_21 * 类说明: */ public class ObjectCloneTest { /** * @param args * @throws CloneNotSupportedException */ public static void main(String[] args) throws CloneNotSupportedException { // TODO Auto-generated method stub Address address=new Address("中国", "北京", "北京"); Employee employee=new Employee("曹艳丰",23,address); System.out.println(employee); Employee employee2=null; ObjectOutputStream out=null; ObjectInputStream in=null; try { out=new ObjectOutputStream(new FileOutputStream("employee.dat")); out.writeObject(employee); in=new ObjectInputStream(new FileInputStream("employee.dat")); employee2=(Employee)in.readObject(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(employee2); } } /** * 创建时间:2014年9月8日 下午2:38:13 项目名称:Test * * @author Cao Yanfeng * @since JDK 1.6.0_21 类说明: */ public class Employee implements Serializable { /** * 序列号 */ private static final long serialVersionUID = 1L; private String name; private int age; private Address address; /** * */ public Employee(String name, int age, Address address) { // TODO Auto-generated constructor stub this.name = name; this.age = age; this.address = address; } @Override public String toString() { // TODO Auto-generated method stub return "姓名:" + name + ",年龄:" + age + ",地址——" + address; } //省略set()和get()函数 } /** * 创建时间:2014年9月8日 下午2:52:18 项目名称:Test * * @author Cao Yanfeng * @since JDK 1.6.0_21 类说明: */ 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) { // TODO Auto-generated constructor stub this.state = state; this.province = province; this.city = city; } @Override public String toString() { // TODO Auto-generated method stub StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("国家:" + state + ","); stringBuilder.append("省:" + province + ","); stringBuilder.append("市:" + city); return stringBuilder.toString(); } //省略set()和get()函数 }
Java对象的复制方法总结
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。