java IO流讲到序列化和反序列化,其实就是把对象写到文件中而已,它也是创建对象的一种方式
反序列化------------输入流
序列化--------------输出流
注意序列化和反序列化顺序要保持一致,先序列化然后反序列化
不是所有的对象都可以序列化,必须实现Serializable接口,
public interface Serializable {
}
它就是一个标记接口,并没有什么实现方法,
现在写个demo玩下:
import java.io.Serializable;
public class Student implements Serializable{
private String name;
private int age;
private String province;
private double salary;
public Student(String name, int age, String province, double salary) {
super();
this.name = name;
this.age = age;
this.province = province;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
测试
import java.io.File;
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 Demo1 {
public static void main(String[] args) {
Student st = new Student("zhouguizhi",23,"江西省",1000);
System.out.println("st="+st);
seria(st);
deseria();
}
/**
* 反序列化
*/
private static void deseria() {
FileInputStream fis = null;
ObjectInputStream ois = null;
try
{
File file = new File("D://student.txt");
fis = new FileInputStream(file);
ois = new ObjectInputStream(fis);
Student stu = (Student) ois.readObject();
System.out.println("反序列化后的对象stu="+stu);
System.out.println("name = " + stu.getName());
System.out.println("age = " + stu.getAge());
System.out.println("province = " + stu.getProvince());
System.out.println("salary = " + stu.getSalary());
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}finally{
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ois!=null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 序列化
*/
private static void seria(Student stu) {
if(stu!=null){
File file = new File("D://student.txt");
//Student对象序列化过程
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream(file);
oos = new ObjectOutputStream(fos);
oos.writeObject(stu);
oos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(oos!=null)
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fos!=null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
log日记:
st=Student@2a139a55
反序列化后的对象stu=Student@232204a1
name = zhouguizhi
age = 23
province = 江西省
salary = 1000.0
你会发现反序列化的对象上的属性值是一样的,但是对象不是同一个对象,再看下生成的文件:
反序列化后的对象stu=Student@232204a1
name = zhouguizhi
age = 23
province = 江西省
salary = 1000.0
你会发现反序列化的对象上的属性值是一样的,但是对象不是同一个对象,再看下生成的文件:
现在思考下单例模式,真的安全么,如果我用序列化和反序列化出来,还能保证它对象是唯一性么,在内存中只有一个么,好像不能保证吧,至于怎么解决 不说了好像我单例模式那篇博客有讲,而且原型设计模式也会设计到这块知识
比如我现在有个需求就是我Student中的salary不想被反序列化怎么办呢?在java中有一个关键词修饰就可以transient。
private transient double salary;
我现在把属性salary不想被反序列化,再次运行看看结果:
st=Student@2a139a55
反序列化后的对象stu=Student@232204a1
name = zhouguizhi
age = 23
province = 江西省
salary = 0.0
发现没有salary只是默认初始化值,并不是跟上次一样是1000.00
反序列化后的对象stu=Student@232204a1
name = zhouguizhi
age = 23
province = 江西省
salary = 0.0
发现没有salary只是默认初始化值,并不是跟上次一样是1000.00
总结:
序列化时,只对对象的状态进行保存,而不管对象的方法
当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口
当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化
序列化时,只对对象的状态进行保存,而不管对象的方法
当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口
当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化