Java 序列化 和 反序列--by Vincent
序列化:
Java 提供了一种把对象序列化的机制。
即把一个对象可以被表示为一个字节序列。然后可以写入文件保存。
字节序列包括:
该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。
有点和C语言的结构体类似。
反序列化:
将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,提高一个对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中重新恢复出来一个“一样的”新对象。
序列化和反序列都是跨平台,和本地环境无关。
因为整个过程都是Java虚拟机(JVM)独立的,平台无法的,所以跨平台。在一个平台上序列化的对象可以在另一个完全不同的平台上反序列化该对象。
类——都属于Java.io包
- ObjectInputStream(对象输入流---反序列化)
- ObjectOutputStream(对象输出流--序列化)
这俩类是高层次的数据流,它们包含序列化和反序列化对象的方法。
【注意点】
ObjectOutputStream 类里的
public final void writeObject(Object x) throws IOException{
} //序列化一个对象,并把它发送到输出流.
ObjectInputStream 类里的
public final Object readObject() throws IOException,ClassNotFoundException{
} //从流里面读取下一个对象,并将对象反序列化,但是你要注意它的返回值是object类型所以你要将它转为合适的数据类型也就是你要整了你需要的object对象类型。
Serializable 接口
- 一个对象想要序列化。那么这个类必须继承Serializable接口。
-
- javaAPI里的标准类是不是可以被序列化那么有查看原文档。看源文档有没有实现这个接口>
- 这个类的所有属性必须是可序列化的,如果有一个属性不是可序列化的,则该属性必须注明是短暂的,必须注明。
transient--注明是短暂
这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
实现下。
【一个可序列化的类】
/** * @author 谢杰 * 测试序列化。该类实现了serializable接口。 */ public class Student implements java.io.Serializable{ public String name; public String address; public int account; public <span style="background-color: rgb(102, 255, 153);">transient </span>int password; //transient password设置为不可序列化 public void mailCheck() { System.out.println("Mailing a check to " + name + " " + address); } }
【序列化】
当序列化一个对象到文件时, 按照Java的标准约定是给文件一个.ser扩展名
import java.io.*; public class StudentSerialize_Out { public static void main(String [] args) { Student e = new Student(); e.name = "Vincent"; e.address = "harbin/china"; e.password = 11122333; e.account = 101; try { FileOutputStream fileOut = new FileOutputStream("<span style="background-color: rgb(102, 255, 153);">F://Student.ser</span>"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(e); out.close(); fileOut.close(); System.out.printf("Serialized data is saved in F://Student.ser"); }catch(IOException i) { i.printStackTrace(); } }}
【成功输出在F盘。。。】
【我们用记事本打开 .ser查看里面的字符。】
可以看到没有 password
【反序列化】
import java.io.*; public class StudentSerialize_Input { public static void main(String [] args) { Student e = null; try { FileInputStream fileIn = new FileInputStream("F://Student.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); e = (Student) in.readObject(); //注意这里要把返回来的object类型转换 in.close(); fileIn.close(); }catch(IOException i) { i.printStackTrace(); return; }catch(ClassNotFoundException c) { System.out.println("Student class not found"); c.printStackTrace(); return; } System.out.println("Deserialized Student..."); System.out.println("Name: " + e.name); System.out.println("Address: " + e.address); System.out.println("password: " + e.password); System.out.println("account: " + e.account); } }