对象序列化:Serialize-将一个java对象写入IO流中
对象反序列化:Deserialize-从IO流中恢复java对象
类可序列化:实现接口Serializable或Externalizable
class Person implements Serializable { public String name; public int age; public Person(String name, int age) { this.name = name; this.age = age; } }
1.使用对象流序列化
public static void main(String[] args) { //序列化 ObjectOutputStream oos=null; try { oos= new ObjectOutputStream( new FileOutputStream("D:\\testjava\\jianzhioffer\\testS.txt")); Person p=new Person("hahaha", 15); oos.writeObject(p); } catch (Exception e) { e.printStackTrace(); } finally{ try{ if(oos!=null){ oos.close(); } }catch(Exception e){ e.printStackTrace(); } }
}
反序列化
ObjectInputStream ois=null; try{ ois=new ObjectInputStream(new FileInputStream("D:\\testjava\\jianzhioffer\\testS.txt")); Person p=(Person)ois.readObject(); System.out.println("名字是:"+p.name+","+"年龄是:"+p.age); }catch(Exception e){ e.printStackTrace(); }finally{ try{ if(ois!=null){ ois.close(); } }catch(Exception e){ e.printStackTrace(); } }
2. 对象引用的序列化
如果序列化类的属性是引用类型,那么这个引用类型要是可序列化的,否则外层类不能序列化
假设,B,C都引用了A类,B和C序列化时候,对A重复序列化,反序列化时候,得到三个A,是不一样的,违背了序列化初衷:
解决:每个对象保存一个编号,序列化时候,已经序列化过的不再序列化,返回编号
//对象序列化 ObjectOutputStream oost=null; try{ oost=new ObjectOutputStream(new FileOutputStream("D:\\testjava\\jianzhioffer\\testT.txt")); Person p=new Person("student", 1); Teacher t1=new Teacher("teacher1", p); Teacher t2=new Teacher("teacher2", p); oost.writeObject(t1); oost.writeObject(t2); oost.writeObject(p); oost.writeObject(t2); }catch(Exception e){ e.printStackTrace(); }finally{ try{ if(oost!=null){ oost.close(); } }catch(Exception e){ e.printStackTrace(); } } //对象反序列化 ObjectInputStream oist=null; try{ oist=new ObjectInputStream(new FileInputStream("D:\\testjava\\jianzhioffer\\testT.txt")); Teacher t1=(Teacher)oist.readObject(); Teacher t2=(Teacher)oist.readObject(); Person p=(Person)oist.readObject(); Teacher t3=(Teacher)oist.readObject(); System.out.println("t1的student引用与p是否相同:"+(t1.student==p)); System.out.println("t2的student引用与p是否相同:"+(t2.student==p)); System.out.println("t3的student引用与p是否相同:"+(t3.student==p)); }catch(Exception e){ e.printStackTrace(); }finally{ try{ if(oist!=null){ oist.close(); } }catch(Exception e){ e.printStackTrace(); } }
存在问题:无法序列化可变对象
解决:1. 属性加transient关键字,每次序列化不理会该属性,但是隔离在序列化机制之外
2. 自定义序列化
使用Externalizable接口
void readExternal(ObjectInput in)
void witeExternal(ObjectOutput out)
原文:https://www.cnblogs.com/jieyi/p/14294411.html