将基本数据类型转化为字节的形式称为[序列化]
从字节转换为其对应的基本类型数据称为[反序列化]
将数据保存到磁盘中称为[持久化]
transient关键字,被该关键字修饰的属性,不会被序列化
序列化实现 implements Serializable
对象序列化与反序列化
ObjectInputStream:将字节读入并转换为其描述的对象
ObjectOutputStream:将给定的对象转成字节并写出
对象的属性有两类:
1.基本类型属性:将基本类型数据的值直接转化为字节
2.引用类型属性:这里会递归操作,先将该对象转化为字节
import java.io.Serializable;
import java.util.Objects;
/**
* 可以被序列化的类
* 想要序列化,该类必须实现序列化接口
*/
public class Person implements Serializable {
private String name;
/*
transient关键字
被该关键字修饰的属性,不会被序列化
*/
private transient int age;
public Person(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "名字:"+name+"年龄:"+age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
import java.io.*;
/**
* 测试对象序列化
* 使用ObjectOutputStream
*/
public class TestObjectOutputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//创建一个想被序列化的对象
Person person=new Person("张三",22);
FileOutputStream fos=new FileOutputStream("object.dat");
ObjectOutputStream oos=new ObjectOutputStream(fos);
/*
* 所有通过objectoutputstream进行序列化的对象
* 必须都要实现序列化接口,否则在序列化过程中就会报错
* 接口:Serializable
*/
oos.writeObject(person);
oos.close();
FileInputStream fis=new FileInputStream("object.dat");
ObjectInputStream ois=new ObjectInputStream(fis);
Person p=(Person)ois.readObject();
System.out.println("对象内容是否一致"+person.equals(p));//true
System.out.println("对象是否是同一个"+(person==p));//false
ois.close();
}
}
浅表复制
>import java.util.ArrayList;
/**
* 浅表复制
* 只复制外观,内部不复制
*/
public class CloneObject {
public static void main(String[] args) {
ArrayList<Person> list=new ArrayList<Person>();
list.add(new Person("张三",11));
list.add(new Person("李四",22));
list.add(new Person("王五",33));
ArrayList<Person> clone=(ArrayList<Person>)list.clone();
//内容一样
System.out.println(list.equals(clone));
//不是一个对象
System.out.println(clone==list);
//两个集合的元素的内容一样
System.out.println(clone.get(0).equals(list.get(0)));
clone.get(0).setName("张三三");
System.out.println(list.get(0));//名字:张三三年龄:11
}
}
复制构造器
>import java.util.ArrayList;
import java.util.HashSet;
/**
* 集合的复制构造器
*/
public class CopyCollection {
public static void main(String[] args) {
/*
在对集合进行浅表复制的时候,可以使用集合的复制
构造器
*/
ArrayList<Person> person=new ArrayList<Person>();
person.add(new Person("张三",11));
person.add(new Person("李四",22));
/*
复制构造器
ArrayList(Collection c)
*/
//等同ArrayList<Person> clone=(ArrayList<Person>)list.clone();
ArrayList<Person> clone=new ArrayList<Person>(person);
/*
将一个List集合转换为一个Set集合
*/
HashSet<Person> set=new HashSet<Person>(clone);
System.out.println(set);
}
}
> import java.util.ArrayList; import java.util.List;
>
> public class CloneDemo {
> List<Person> list=new ArrayList<Person>();
> /*
> 报错,list中没有clone()方法
> List是接口,不继承object
> 所以不能clone
> */
> //List<Person> clone=list.clone(); X }
> //可以这样
> List<Person> clone=new ArrayList<Person>(list);
>
使用对象序列化与反序列化操作进行对对象的深度复制
先将Person中private transient int age;改为private int age;