java编程思想笔记(十六)对象序列化
java对象序列化是将对象转化成一个字节序列,一般是将对象实现Serializable接口来实现对象序列化,序列化后,可以通过网络传输数据,也能存在数据库或硬盘中。
反序列化则是字节序列转为JAVA对象
下面是实现Serializable接口后对象序列化和反序列化的栗子:
import java.io.*; public class TestObject implements Serializable{} import java.io.*; //序列化 public class SerializeObject{ public static void main(String[] args)throws Exception{ ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(“x.file”)); TestObject obj = new TestObject(); //将TestObject对象序列化到x.file文件中 out.write(obj); } } import java.io.*; //反序列化 public class DeserializeObject{ public static void main(String[] args)throw Exception{ ObjectInputStream in = new ObjectInputStream(new FileInputStream(“x.file”)); Object myObj = in.readObject(); System.out.println(myObj.getClass()); } }输出结果:
class TestObject
在序列化时,使用ObjectOutputStream将对象序列化写出,反序列化时,使用ObjectInputStream将对象反序列化读入。
注意:反序列化对象使用时,对象的class文件必须在classpath中,否则,JVM找不到对象的class文件会抛出ClassNotFoundException。
2.序列化控制
用Serializable会把整个对象都给序列化,使用Externalizable则把对象部分序列化,Externalizable需要实现2个方法,一个是writeExternal(ObjectOutput out),另一个是readExternal(ObjectInput in),把你想序列化的对象写在writeExternal方法中,反序列化的对象写在readExternal方法中,在对象序列化和反序列化过程中,这两个方法会自动调用。
import java.io.*; class Blip1 implements Externalizable{ public Blip1(){ System.out.println(“Blip1 Constructor”); } public void writeExternal(ObjectOutput out)throws IOException{ System.out.println(“Blip1.writeExternal”); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException{ System.out.println(Blip1.readExternal); } } class Blip2 implements Externalizable{ Blip1(){ System.out.println(“Blip2 Constructor”); } public void writeExternal(ObjectOutput out)throws IOException{ System.out.println(“Blip2.writeExternal”); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException{ System.out.println(Blip2.readExternal); } } public class Blips{ public static void main(String[] args)throws IOException, ClassNotFoundException{ System.out.println(“Constructing objects:”); Blip1 b1 = new Blip1(); Blip2 b2 = new Blip2(); //序列化 ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(“Blips.out”)); System.out.println(“Saving objects:”); o.writeObject(b1); o.writeObject(b2); //反序列化 ObjectInputStream in = new ObjectInputStream(new FileInputStream(“Blips.out”)); System.out.println(“Recovering b1:”); b1 = (Blip1)in.readObject(); //由于Blip2的默认无参数构造方法不是public的,所以会抛异常 //System.out.println(“Recovering b2:”); //b2 = (Blip2)in.readObject(); } }
输出结果:
Constructing objects:
Blip1 Constructor
Blip2 Constructor
Saving objects:
Blip1.writeExternal
Blip2.writeExternal
Recovering b1:
Blip1 Constructor
Blip1.readExternal
3.Externalizable指定部分字段初始化
用writeExternal()和readExternal()可指定所需字段去初始化,不需要的则不初始化
import java.io.*; public class Test implements Externalizable{ private int i; private String s; public Test(){ System.out.println(“Test Constructor”); } public Test(String x, int a){ System.out.println(“Test(String x, int a)”); i = a; s = x; } public void toString(){ return s + i; } public void writeExternal(ObjectOutput out)throws IOException{ System.out.println(“Test.writeExternal”); out.writeObject(s); out.writeInt(i); } public void readExternal(ObjectInput in)throws IOException, ClassNotFoundException{ System.out.println(“Test.readExternal”); s = (String)in.readObject(); i = in.readInt(); } public static void main()throws IOException, ClassNotFoundException{ System.out.println(“Constructing objects:”); Test t1 = new Test(“A String”, 47); Test t2 = new Test(); System.out.println(t1); System.out.println(t2); //序列化 ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(“Test.out”)); System.out.println(“Saving objects:”); o.writeObject(t1);\ o.writeObject(t2); o.close(); //反序列化 ObjectInputStream in = new ObjectInputStream(new FileInputStream(“Test.out”)); System.out.println(“Recovering objects:”); t1 = (Test)in.readObject(); System.out.println(t1); t2 = (Test)in.readObject(); System.out.println(t2); } }
输出结果:
Constructing objects:
Test(String x, int a)
A String 47
Test Constructor
null0
Saving objects:
Test.writeExternal
Test.writeExternal
Recovering objects:
Test Constructor
Test.readExternal
A String 47
Test Constructor
Test.readExternal
null 0
该例子中,当创建对象使用非无参数构造方法时,对象字段被初始化,因此序列化时可以将初始化的值保存。当创建对象使用无参数的构造方法时,对象的字段没有被赋值而使用默认的初始化值。t1使用readExternal()反序列化时因为没有参数,所以会调用默认构造器.
4.transient关键字:
当类中某些字段不想被序列化,就需要使用transient关键字,适用于自动序列化的Serializable , Externalizable可通过writeExternal()方法也可以实现此功能.
例子如下:
import java.io.*; public class User implements Serializable{ private String username; private transient String password; public User(String name, String pwd){ username = name; password = pwd; } public String toString(){ return “username:” + username + “, password:” + password; } public static void main(String[] args)throws Exception{ User user = new User(“Test”, “passwd”); System.out.println(“User=” + user); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(“User.out”)); o.writeObject(user); o.close(); ObjectInputStream in = new ObjectInputStream(new FileInputStream(“User.out”)); System.out.println(“Recovering object:”); user = (User)in.readObject(); System.out.println(“User=” + user); } }
输出结果:
User=username:Test,password:passwd
Recovering object:
User=username:Test,password:null
上一篇: js实现筛选功能
下一篇: 改进Python文字小游戏