当我们想对一个对象进行操作但是还想保留原有数据进行接下来的操作时,我们可以便可以使用对象拷贝。
对象拷贝分为深拷贝和浅拷贝。浅拷贝就是只复制对象的引用地址,而对象的内容不进行复制。深拷贝就是将一个对象的引用地址及其内容全部拷贝。
实现对象拷贝的方式有两种?
1、让被拷贝的类实现cloneable接口,然后在类里面重写Object类的clone()方法。
2、让被拷贝的那个类实现serilzable接口,通过流来实现对象的拷贝。
第一种实现了浅拷贝;推荐使用第二种,因为第二种不但实现了深拷贝,而且还可以加泛型限定,拷贝对象在编译阶段就可以检查出是否支持序列化。
下面这段代码是引用一位大佬的,我以此为例进行分析
public class ObjectSerializationDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
File file = new File("D:\\person.out");
if(!file.exists()){
file.mkdirs();
}
//2、序列化 对象---》objiect流---》文件流---》writeObject(被拷贝对象)写入文件中
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
Person person = new Person("测试",25,Gender.FEMALE,"ennenen");
oos.writeObject(person);
oos.close();
//3、反序列化 文件----》文件流---》object流---》readObject()获取到流中的对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
Person person1 = (Person) ois.readObject();
System.out.println(person1);
}
}
/**
* 1、实现Serializable 表示该类可以被序列化
*/
public class Person implements Serializable {
private String name ;
private Integer age;
private Gender gender;
/**
* transient 的作用是防止变量被序列化,在反序列化的时候transient 变量的值被赋值为初始值
* transient 只能修饰变量,不能修饰其他的成分
*/
private transient String introduce;
public Person() {
System.out.println("none-arg constructor");
}
public Person(String name, Integer age, Gender gender,String introduce) {
System.out.println("arg constructor");
this.name = name;
this.age = age;
this.gender = gender;
this.introduce = introduce;
}
//省略get 和 set 方法
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
", introduce='" + introduce + '\'' +
'}';
}
}
大佬的代码虽好但是没有加泛型限定,其实也没啥就是将序列化和反序列化的那段代码拿出来放在一个方法里,在方法的返回值类型上增加一个泛型如 extend Serializable>。
引用文章:https://blog.csdn.net/weixin_43610698/article/details/110136372