通俗来说就是将对象的信息保存在文件里.方便传输
下面是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对象的构造必须先有父对象,才有子对象,反序列化也不例外。
所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。
这是原理, 简答来说就是,当父类没有实现序列化接口,反序列化子类时会调用父类默认的构造方法.
代码就在上面,修改一下试试就知道了
基本就是这样.
如果有人看完没懂的话可以留言提问,我尽量解答,虽然我也很菜