一、使用clone复制
public class CloneTest { public static void main(String[] args) { Person p1 = new Person("张居正",10,new StringBuffer("男"),new Address("北京",3008)); System.out.println("被clone之前的p1=="+p1); Person p2 = (Person) p1.clone(); System.out.println("克隆产生的p2=="+p2); System.out.println("***********************************"); p2.name = "戚继光"; p2.age = 12; p2.sex.append("猛男"); p2.address.city = "天津"; p2.address.number = 9000; System.out.println("改变p2的属性之后:"); System.out.println("p1=="+p1); System.out.println("p2=="+p2); System.out.println("p1和p2的属性都不相等,证明确实实现了深层复制!"); } } //Address类型属于能够直接调用clone方法实现深层复制的其他类型 class Address implements Cloneable{ public String city; public int number; public Address(String city,int number){ this.city = city; this.number = number; } @Override public Object clone() throws CloneNotSupportedException{ return super.clone(); } @Override public String toString(){ return "city="+city+";number="+number; } } //用于序列化的类 //第一,必须实现java.lang.Cloneable接口 class Person implements Cloneable{ //第二,所有属性必须是基本数据类型、String、StringBuffer类型,或者能够直接调用clone方法实现深度复制的其他类型 //注意:StringBuffer类型不能够直接调用clone方法实现直接复制 public String name; public int age; public StringBuffer sex; public Address address; public Person( String name,int age, StringBuffer sex, Address address){ this.name = name; this.age = age; this.sex = sex; this.address = address; } //第三,必须重写clone方法 @Override public Object clone(){ Person p = null; try { //第四,对于基本数据类型和String类型,在调用super.clone()方法时,就已经复制成功了 p = (Person) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } //第五,如果属性是StringBuffer类型,则需要使用下面是形式再次给属性赋值 p.sex = new StringBuffer(this.sex.toString()); //第六,如果实行不是基本数据类型、String、StringBuffer类型,则使用一下进行属性的深层复制 try { p.address = (Address) address.clone(); } catch (CloneNotSupportedException e) { p.address = null; e.printStackTrace(); } return p; } @Override public String toString(){ return "name="+name+";age="+age+";sex="+sex.toString()+";address={"+address+"}"; } }
运行结果:
被clone之前的p1==name=张居正;age=10;sex=男;address={city=北京;number=3008} 克隆产生的p2==name=张居正;age=10;sex=男;address={city=北京;number=3008} *********************************** 改变p2的属性之后: p1==name=张居正;age=10;sex=男;address={city=北京;number=3008} p2==name=戚继光;age=12;sex=男猛男;address={city=天津;number=9000}
p1和p2的属性都不相等,证明确实实现了深层复制!
二、使用序列化复制
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 SerializableTest { public static void main(String[] args) throws IOException, ClassNotFoundException { Person p1 = new Person("张居正",10,new StringBuffer("男")); System.out.println("序列化之前的p1=="+p1); byte [] bytes = serializeToByte(p1); Person p2 = (Person)deserializeToObject(bytes); System.out.println("反序列化之后的p2=="+p2); System.out.println("***********************************"); p2.name = "戚继光"; p2.age = 12; p2.sex.append("猛男"); System.out.println("改变p2的属性之后:"); System.out.println("p1=="+p1); System.out.println("p2=="+p2); System.out.println("p1和p2的属性都不相等,证明确实实现了深层复制!"); } //将Java对象序列化为byte数组 public static byte [] serializeToByte(Object obj) throws IOException{ ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteOut); out.writeObject(obj); return byteOut.toByteArray(); } //将byte数组反序列化为Java对象 public static Object deserializeToObject(byte [] bytes) throws IOException, ClassNotFoundException{ ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes); ObjectInputStream in =new ObjectInputStream(byteIn); return in.readObject(); } } //用于序列化的类,必须实现java.lang.Serializable接口 class Person implements Serializable{ public String name; public int age; public StringBuffer sex; public Person(String name,int age,StringBuffer sex){ this.name = name; this.age = age; this.sex = sex; } @Override public String toString(){ return "name="+name+";age="+age+";sex="+sex.toString(); } }
注意:被序列化的对象的类必须已经实现java.lang.Serializable接口。
运行结果:
序列化之前的p1==name=张居正;age=10;sex=男 反序列化之后的p2==name=张居正;age=10;sex=男 *********************************** 改变p2的属性之后: p1==name=张居正;age=10;sex=男 p2==name=戚继光;age=12;sex=男猛男
p1和p2的属性都不相等,证明确实实现了深层复制!
参考文章:http://www.ibm.com/developerworks/cn/java/l-jpointer/index.html
相关推荐
Java中的对象复制与克隆是程序开发中常见的需求,主要用于创建一个对象的副本,而不会影响原始对象的状态。这里主要讨论两种类型的对象拷贝:浅拷贝和深拷贝。 浅拷贝,也称为表面拷贝,是创建一个新的对象,然后将...
Java对象序列化是Java开发中的一个重要概念,它允许我们将Java对象转换为字节流,以便存储、传输或在不同时间点恢复。以下是五个可能不为人知的关于Java对象序列化的知识点,这些知识点对于深入理解Java开发至关重要...
- **深层复制**:递归地复制了所有的对象,确保复制的对象完全独立于原始对象。 - **实现方式**:可以通过实现`Cloneable`接口并重写`clone()`方法来实现浅层复制,而对于深层复制,可以通过序列化和反序列化来...
基本类型的赋值是将一个值赋值给另一个值,而对象之间的赋值是将一个对象的reference从某处复制到另一处,可能会导致别名现象。 解决别名的方法 可以通过clone方法来解决别名问题。clone方法可以制作某个对象的...
因此,所有Java对象默认都具备`clone()`能力。但是,为了使用它,我们需要覆盖`clone()`方法,并且确保类实现了`Cloneable`接口,以避免抛出异常。 测试代码通常会包括以下步骤: 1. 实现`Cloneable`接口。 2. ...
A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...
clone方法执行的是浅表复制,而不是深层复制操作。 使用clone方法需要实现java.lang.Cloneable接口,并重写protected方法clone。如果没有实现Clonebale接口会抛出CloneNotSupportedException。在克隆java对象的时候...
A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 其他J/Direct...
A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...
A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...
在IT领域,尤其是在编程中,理解“深层复制”是一个至关重要的概念,特别是在处理对象和数据结构时。这个项目,"U10316040_HW5_15_10",显然是一个旨在帮助学习者深入理解深层复制的实践任务。在Java语言环境下,...
A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...
A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...
然而,Java的标准库并不直接支持深拷贝,因为Java的`clone()`方法默认执行的是浅拷贝,只复制对象本身而不复制其引用的对象。因此,开发者需要自定义实现深拷贝机制。本文将详细讲解如何在Java中实现深拷贝,并提供...
总的来说,《Java深度历险》是一本适合有基础的Java开发者阅读的书籍,它能带领你探索Java的深层世界,提升你的技术水平。通过学习,你不仅可以理解Java的运作机制,还能掌握解决实际问题的技巧,为你的Java开发事业...
- 对象序列化是指将Java对象的状态转换为字节序列的过程,以便于存储或在网络中传输。 - 反序列化则是将字节序列还原为原始Java对象的过程。 - 序列化和反序列化涉及使用`java.io.Serializable`接口标记可序列化的类...
A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...
A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调...
A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...