序列化:把要传输的对象以及相关信息转成对应的字节数组进行存储即 将一个java对象写入IO流中。
反序列化:把字节数组转回成相应的对象 即从IO流中恢复该对象。
主要作用于数据传输
如果把要传输的对象以及相关信息(非静态属性)转成对应的字节数组进行存储,并把该字节数组存储在硬盘上,这个过程就是持久化,持久化包含序列化。
数据落地就是把数据放到本地硬盘上做了持久化。
实现序列化的类ObjectOutputStream
反序列化的类 ObjectInputStream 这是一个处理流,所以必须建立在其他节点流的基础之上。
序列化和反序列化要注意以下几点
1.对象要进行序列化,要保证对象对应的类要实现Serializable接口或者Externalizable接口 ,Serialzable接口时一个标记接口。实现该接口无需实现任何方法,它只是表明该类的实例是可序列化的
2.序列化的是对象和相关属性(静态属性不能序列化)
3.给非静态属性添加transient关键词 就是表示该属性不能被序列化
4.实现Serializable接口的这个类如果没有指定序列化版本号(serialVersionUID),java在底层
就会根据属性和方法算出当时的版本号,这个算出来的版本号就会随着对象一起序列化出去
反序列化的时候就会获取到序列化过来的版本号,去计算此时的类的属性和方法版本号,反序列化
的时候就会拿着序列化过来的版本号和刚才计算好的版本号进行比较,如果两个版本号相等就反序列化
成功,如果两个序列化的版本号不相等就反序列失败
所以为了让我们在可以在改动类属性的情况下保持序列化和反序列化的版本号一致保证每次反序列化成功。 要自己指定序列化版本号
5.集合和映射对象都不能序列化,只能遍历集合或者映射一一去序列化存储的对象
序列化对象
import java.io.Serializable; import org.omg.CORBA.PRIVATE_MEMBER; //想要实现序列化就是实现Serializable接口 public class Person implements Serializable { /** * java提供的序列化版本号 */ private static final long serialVersionUID = 1L; private String name; private int age; //静态属性不能序列化 static String classRoom; //transient 代表该属性不能被序列化 private transient double tall; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static void main(String[] args) { } }
序列化
//java.io.NotSerializableException ---没有序列化异常 //带able的异常大多都是没有实现接口 //想要实现序列化就是实现Serializable接口 public class ObjectOutputStreamDemo { public static void main(String[] args) throws FileNotFoundException, IOException { //创建对象 Person p=new Person(); //给对象属性赋值 p.setName("徐旺骑"); p.setAge(24); //进行序列化---创建序列化对象 ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream("p.data")); //写出对象 oos.writeObject(p);//把对象进行序列化 //关流 oos.close(); } }
上面代码创建了一个ObjectOutputStream,这个ObjectOutputStream输出流建立在一个文件输出流的基础上,再用writeObject方法将一个Person对象写入输出流。运行上面程序,就会生成一个p.data文件,该文件的内容就是Person对象。
反序列化
public class ObjectInputStreamDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { //创建反序列化对象 ObjectInputStream ois =new ObjectInputStream(new FileInputStream("p.data")); //读取对象 ----保证获取的是传入的对象 Person p=(Person)ois.readObject(); //用对象原来的类型来接收数据 //关流 ois.close(); //获取对象属性 System.out.println(p.getName()+p.getAge()); //徐旺骑24 } }