java中浅拷贝和深拷贝
时间: 2023-07-22 21:05:17 浏览: 106
在Java中,浅拷贝和深拷贝都是用于复制对象的概念。
浅拷贝是指创建一个新对象,然后将原始对象的非静态字段复制到新对象中。如果字段是基本类型,则对该字段执行逐位复制;如果字段是引用类型,则复制引用而不是引用的对象。
深拷贝是指创建一个新对象,然后递归地复制原始对象及其所有引用的对象。这意味着在深拷贝中,即使字段是引用类型,也会创建一个新的对象并复制其内容。
要实现浅拷贝,可以使用`clone()`方法。该方法在`Object`类中定义,并且可以由任何类继承和覆盖。要使一个类支持克隆,需要实现`Cloneable`接口,并且覆盖`clone()`方法。
示例代码如下:
```java
class MyClass implements Cloneable {
private int value;
private MyObject obj;
public MyClass(int value, MyObject obj) {
this.value = value;
this.obj = obj;
}
public int getValue() {
return value;
}
public MyObject getObj() {
return obj;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class MyObject {
private String name;
public MyObject(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
MyObject obj = new MyObject("Object 1");
MyClass obj1 = new MyClass(10, obj);
MyClass obj2 = (MyClass) obj1.clone();
System.out.println(obj1.getObj().getName()); // Output: Object 1
System.out.println(obj2.getObj().getName()); // Output: Object 1
obj.setName("Object 2");
System.out.println(obj1.getObj().getName()); // Output: Object 2 (原始对象和浅拷贝对象引用同一个对象)
System.out.println(obj2.getObj().getName()); // Output: Object 2
}
}
```
需要注意的是,浅拷贝只复制了对象的引用,而不是对象本身。因此,如果修改了原始对象中的引用对象,那么浅拷贝对象也会受到影响。
要实现深拷贝,可以使用序列化和反序列化。通过将对象写入字节流,然后从字节流读取对象,可以创建一个全新的对象。这种方法需要确保所有相关的类都实现了`Serializable`接口。
示例代码如下:
```java
import java.io.*;
class MyClass implements Serializable {
private int value;
private MyObject obj;
public MyClass(int value, MyObject obj) {
this.value = value;
this.obj = obj;
}
public int getValue() {
return value;
}
public MyObject getObj() {
return obj;
}
}
class MyObject implements Serializable {
private String name;
public MyObject(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Main {
public static <T> T deepCopy(T object) throws IOException, ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (T) ois.readObject();
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
MyObject obj = new MyObject("Object 1");
MyClass obj1 = new MyClass(10, obj);
MyClass obj2 = deepCopy(obj1);
System.out.println(obj1.getObj().getName()); // Output: Object 1
System.out.println(obj2.getObj().getName()); // Output: Object 1
obj.setName("Object 2");
System.out.println(obj1.getObj().getName()); // Output: Object 1 (原始对象和深拷贝对象引用不同的对象)
System.out.println(obj2.getObj().getName()); // Output: Object 1
}
}
```
通过序列化和反序列化可以实现深拷贝,因为它会创建一个全新的对象,而不是引用原始对象的对象。这样,即使修改了原始对象中的引用对象,深拷贝对象也不会受到影响。
阅读全文