通俗来说就是将对象的信息保存在文件里.方便传输
下面是demo代码
先创建一个普通的类.
记得要先接上序列化接口,就是Serializable接口
记得重写toString方法,不然打印对象信息时会打印对象信息的内存地址.
package encodetest; import java.io.Serializable; public class Student implements Serializable { private String stuno; private String stuname; private int stuage; public Student() { } public Student(String stuno, String stuname, int stuage) { super(); this.stuno = stuno; this.stuname = stuname; this.stuage = stuage; } public String getStuno() { return stuno; } public void setStuno(String stuno) { this.stuno = stuno; } public String getStuname() { return stuname; } public void setStuname(String stuname) { this.stuname = stuname; } public void setStuage(int stuage) { this.stuage = stuage; } public int getStuage() { return stuage; } @Override public String toString() { // TODO Auto-generated method stub return "Student[stuno="+stuno+",stuname="+stuname+",stuage="+stuage+"]"; } }然后单独开一个类专门用于序列化对象
package encodetest; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class Object_Seria_Demo1 { public static void main(String[] args) throws FileNotFoundException, IOException { String file = "demo05.txt"; ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(file)); Student stu = new Student("10001", "张三", 20);//Student类的实类 oos.writeObject(stu); oos.flush();//刷新缓冲区 oos.close();//关闭流 ObjectInputStream ois = new ObjectInputStream( new FileInputStream(file)); try { Student stu1 = (Student) ois.readObject();//提取出来时是object类,需要强转一下 System.out.println(stu1); ois.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }注意这里!!
如何自己写对象属性序列化,看下面的代码,跟上面代码是同一类
简单来说就是给类属性添加transient关键字之后虚拟机不会将该属性序列化,但是依旧可以自己将该属性序列化
自己写一个新的 序列化 与 反序列化 的方法
package encodetest; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class Student implements Serializable { private String stuno; private String stuname; // 添加transient关键字之后,该属性不会被储存到数据文件, // 也就是不会被jvm进行默认的序列化,但是可以自己将该属性序列化 private transient int stuage; public Student() { } public Student(String stuno, String stuname, int stuage) { super(); this.stuno = stuno; this.stuname = stuname; this.stuage = stuage; } public String getStuno() { return stuno; } public void setStuno(String stuno) { this.stuno = stuno; } public String getStuname() { return stuname; } public void setStuname(String stuname) { this.stuname = stuname; } public void setStuage(int stuage) { this.stuage = stuage; } public int getStuage() { return stuage; } @Override public String toString() { // TODO Auto-generated method stub return "Student[stuno=" + stuno + ",stuname=" + stuname + ",stuage=" + stuage + "]"; } // 注意看下面方法中参数的声明类型 // 自己写序列化writeObject方法,让填写了transient关键字的属性也可以序列化 private void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject();// 把虚拟机能默认序列化的元素进行序列化操作 s.writeInt(stuage);// 自己完成stuage的序列化 } // 自己写反序列化方法 private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject();// 把jvm默认可以反序列化的元素进行反序列化 // 将stuage属性从文件中读出来, // 也就是手动完成stuage的反序列化 this.stuage = s.readInt(); } }还有,当父类实现序列化接口时,子类也可以序列化,这和集合的泛型编程差不多.
但是,当子类实现序列化
而父类没有实现的时候,反序列化时,
会调用父类构造方法,可能说的不够清楚,直接上代码吧
package demo; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class Object_Seria_Demo2 { public static void main(String[] args) throws IOException { String file = "demo06.txt"; ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(file)); Foo2 foo2 = new Foo2();// oos.writeObject(foo2);//序列化 oos.flush();// 刷新缓冲区 oos.close(); // 关闭流 ObjectInputStream ois=new ObjectInputStream( new FileInputStream(file)); try { Foo2 foo_2=(Foo2)ois.readObject();//反序列化 } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //普通类 class Foo implements Serializable { public Foo() { System.out.println("foo..."); } } class Foo1 extends Foo{ public Foo1() { System.out.println("foo1..."); } } class Foo2 extends Foo1 { public Foo2() { System.out.println("foo2..."); } }讲一下原理:
父类没有实现Serializable接口时,虚拟机是不会序列化父对象的,而一个Java对象的构造必须先有父对象,才有子对象,反序列化也不例外。
所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。
这是原理, 简答来说就是,当父类没有实现序列化接口,反序列化子类时会调用父类默认的构造方法.
代码就在上面,修改一下试试就知道了
基本就是这样.
如果有人看完没懂的话可以留言提问,我尽量解答,虽然我也很菜
