1.浅拷贝:
- 特点:拷贝出来的对象仍保留原对象的所有引用。
- 缺点:“牵一发而动全身”,即改变我们所拷贝的对象的值,会影响我们原对象的值。
- 实现方法:实现Cloneable接口并覆写其clone()。
- 代码实现:
package www.first;
class People{
private String home;
private float height;
public People(String home,float height){
this.home = home;
this.height = height;
}
public void setHome(String home){
this.home = home;
}
@Override
public String toString() {
return "People{" +
"home='" + home + '\'' +
", height=" + height +
'}';
}
}
class Student implements Cloneable{
private String name;
private People people;
public Student(String name,People people){
this.name = name;
this.people = people;
}
public People getPeople(){
return this.people;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", people=" + people +
'}';
}
}
public class CopyTest {
public static void main(String[] args) throws CloneNotSupportedException {
People people = new People("ShanXi",158F);
Student student = new Student("lin",people);
Student copyStudent = (Student) student.clone();
System.out.println(student);
System.out.println(copyStudent);
}
}
结果如下:
若此时我们修改people对象属性的值:
copyStudent.getPeople().setHome("ShangHai");
System.out.println("-----------------------------------------------------------------");
System.out.println(student);
System.out.println(copyStudent);
结果如下:
2.深拷贝:
- 特点:不论是基本数据类型还是引用数据类型,都重新拷贝一份,拷贝出来的对象产生了新的引用,这样修改互不影响;
- 实现方法:将要拷贝的类实现Serializable接口,自己编写一个myClone(),采用序列化来实现拷贝【student --> byte[] --> copyStudent】
- 代码实现:
package www.first;
import java.io.*;
class People implements Serializable{
private String home;
private float height;
public People(String home,float height){
this.home = home;
this.height = height;
}
public void setHome(String home){
this.home = home;
}
@Override
public String toString() {
return "People{" +
"home='" + home + '\'' +
", height=" + height +
'}';
}
}
class Student implements Serializable{
private String name;
private People people;
public Student(String name,People people){
this.name = name;
this.people = people;
}
public People getPeople(){
return this.people;
}
public Student myClone(Student student){
Student copyStudent = null;
try {
//取得字节输出流对象
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
//选择目标终端为字节流输出对象byteOut
ObjectOutputStream oot = new ObjectOutputStream(byteOut);
//将student变为二进制字节流并输出到目标终端(序列化)
oot.writeObject(student);
//将目标终端接收的字节流对象转为byte[]
byte[] bytes = byteOut.toByteArray();
//取得student的字节输入流对象
ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes);
//选择目标终端为student对象的字节流输入
ObjectInputStream oin = new ObjectInputStream(byteIn);
//将二进制流反序列化为Object对象
copyStudent = (Student) oin.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return copyStudent;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", people=" + people +
'}';
}
}
public class CopyTest {
public static void main(String[] args) throws CloneNotSupportedException {
People people = new People("ShanXi",158F);
Student student = new Student("lin",people);
Student copyStudent = student.myClone(student);
System.out.println(student);
System.out.println(copyStudent);
copyStudent.getPeople().setHome("ShangHai");
System.out.println("-----------------------------------------------------------------");
System.out.println(student);
System.out.println(copyStudent);
}
}
结果如下:
可见,此时修改被拷贝对象的值,不会影响原对象的值,因为此时不是一个引用。