1. 普通序列化 implements Serializable

继承Serializable接口

class Employee implements Serializable {
private String name;
private double salary;
private LocalDate hireDay; public Employee() {
} public Employee(String n, double s, int year, int month, int day) {
name = n;
salary = s;
hireDay = LocalDate.of(year, month, day);
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public double getSalary() {
return salary;
} public void setSalary(double salary) {
this.salary = salary;
} public LocalDate getHireDay() {
return hireDay;
} public void setHireDay(LocalDate hireDay) {
this.hireDay = hireDay;
} public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
} public String toString() {
return getClass().getName() + "[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
}
}
// 1. 普通序列化
Employee employee = new Employee("Harry Hacker", 50000, 1989, 10, 1); try (FileOutputStream personOutputStream = new FileOutputStream("E:\\employee.dat");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(personOutputStream);) {
objectOutputStream.writeObject(employee);
} try (FileInputStream personInputStream = new FileInputStream("E:\\employee.dat");
ObjectInputStream objectInputStream = new ObjectInputStream(personInputStream);) {
Object readObject = objectInputStream.readObject(); if (readObject instanceof Employee) {
Employee tempEmployee = (Employee) readObject;
System.out.println(tempEmployee.toString());
}
}
System.out.println();

执行结果

io.Employee[name=Harry Hacker,salary=50000.0,hireDay=1989-10-01]

2. 关联对象

一个employee被多个Manager关联, 反序列后还是同一个。

// 2. 关联对象	一个employee被多个Manager关联, 反序列后还是同一个
Manager manager1 = new Manager("Carl Cracker", 80000, 1987, 12, 15);
manager1.setSecretary(employee); Manager manager2 = new Manager("Tony Tester", 40000, 1990, 3, 15);
manager2.setSecretary(employee); try (FileOutputStream managerOutputStream = new FileOutputStream("E:\\manager.dat");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(managerOutputStream);) {
objectOutputStream.writeObject(manager1);
objectOutputStream.writeObject(manager2);
} try (FileInputStream managerInputStream = new FileInputStream("E:\\manager.dat");
ObjectInputStream objectInputStream = new ObjectInputStream(managerInputStream);) {
Object readObject1 = objectInputStream.readObject();
Object readObject2 = objectInputStream.readObject(); if (readObject1 instanceof Manager) {
Manager tempManager = (Manager) readObject1;
System.out.println(tempManager.toString());
System.out.println(tempManager.getSecretary().hashCode());
} if (readObject2 instanceof Manager) {
Manager tempManager = (Manager) readObject2;
System.out.println(tempManager.toString());
System.out.println(tempManager.getSecretary().hashCode());
}
}
System.out.println();

执行结果

io.Manager[name=Carl Cracker,salary=80000.0,hireDay=1987-12-15][secretary=io.Employee[name=Harry Hacker,salary=50000.0,hireDay=1989-10-01]]
381259350
io.Manager[name=Tony Tester,salary=40000.0,hireDay=1990-03-15][secretary=io.Employee[name=Harry Hacker,salary=50000.0,hireDay=1989-10-01]]
381259350

3. 忽略冗余字段 transient

不能使用javax.persistence.Trasient,使用关键字 transient

class Employee implements Serializable {
private String name;
private transient double salary;
private LocalDate hireDay;
...
}

执行1的结果

io.Employee[name=Harry Hacker,salary=0.0,hireDay=1989-10-01]

4. 保护性恢复  readResolve()&writeReplace()

writeReplace()    在序列化时会先调用writeReplace方法将当前对象替换成另一个对象(该方法会返回替换后的对象)并将其写入流中;

readResolve()    在readObject调用之后自动调用,它最主要的目的就是让恢复的对象变个样.

对于单例对象, 序列化后取得的对象要与序列化之前的对象一致才行; 可以使用readResolve()在read时做一些处理.

class MySingleton implements Serializable {
private MySingleton() {
} private static final MySingleton INSTANCE = new MySingleton(); public static MySingleton getInstance() {
return INSTANCE;
} private Object writeReplace() throws ObjectStreamException{
return INSTANCE;
} private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}
}

下面代码返回true

MySingleton mySingleton = MySingleton.getInstance();

try (FileOutputStream mySingletonOutputStream = new FileOutputStream("E:\\mySingleton.dat");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(mySingletonOutputStream);) {
objectOutputStream.writeObject(mySingleton);
} try (FileInputStream mySingletonInputStream = new FileInputStream("E:\\mySingleton.dat");
ObjectInputStream objectInputStream = new ObjectInputStream(mySingletonInputStream);) {
Object readObject = objectInputStream.readObject(); if (readObject instanceof MySingleton) {
MySingleton orientation = (MySingleton) readObject; // (1) 没有readResolve()方法时; 序列化new出的是新对象,和原先对象不相等
// (2) 添加readResolve()方法后, 序列化之后调用readObject()时会调用readResolve()方法
System.out.println(mySingleton == orientation);
}
}
System.out.println();



5. readObjectNoData()

数据结构改变后, 调用readObjectNoData()方法.

初始化Person, 指定掌纹

class Person implements Serializable {               
    private static final long serialVersionUID = 8427041451926540477L;     public Person() {  }
    
    private int age;
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }              
}

将其序列化

Person p = new Person();
p.setAge(10); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/person.dat"));
oos.writeObject(p);
oos.flush();
oos.close();

类结构变化后

class Animal implements Serializable {
private String name;
public Animal() { } private void readObjectNoData() {
this.name = "zhangsan";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} class Person extends Animal {
private static final long serialVersionUID = 8427041451926540477L; public Person() { } private int age; public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
}

执行

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:/person.dat"));
Person sp = (Person) ois.readObject();
System.out.println(sp.getName());
ois.close();

得到 zhangsan

6.  Externalizable接口

由开发者完全决定如何序列化和反序列化目标对象

注意: 必须提供一个无参构造器,访问权限为public; 否则会抛出java.io.InvalidClassException 异常

class Student implements Externalizable {
private String name;
private int age; @Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(name);
out.writeInt(age);
} @Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = (String)in.readObject();
age = in.readInt();
} //no valid constructor
//必须提供一个无参构造器,访问权限为public;否则会抛出java.io.InvalidClassException 异常
public Student() {
// TODO Auto-generated constructor stub
} public Student(String name, int age) {
this.name= name;
this.age=age;
} 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;
} @Override
public String toString() {
return "name:"+name+", age: "+age;
}
}

序列化

Student student = new Student("name", 20);

try (FileOutputStream studentOutputStream = new FileOutputStream("E:\\student.dat");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(studentOutputStream);) {
objectOutputStream.writeObject(student);
} try (FileInputStream studentInputStream = new FileInputStream("E:\\student.dat");
ObjectInputStream objectInputStream = new ObjectInputStream(studentInputStream);) {
Object readObject = objectInputStream.readObject(); if (readObject instanceof Student) {
System.out.println(((Student) readObject).toString());
}
}
System.out.println();

结果: name:name, age: 20

7.  为克隆使用序列化

实现深拷贝

class SerialCloneable implements Cloneable, Serializable {
public Object clone() throws CloneNotSupportedException {
try {
// save the object to a byte array
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try (ObjectOutputStream out = new ObjectOutputStream(bout)) {
out.writeObject(this);
} // read a clone of the object from the byte array
try (InputStream bin = new ByteArrayInputStream(bout.toByteArray())) {
ObjectInputStream in = new ObjectInputStream(bin);
return in.readObject();
}
} catch (IOException | ClassNotFoundException e) {
CloneNotSupportedException e2 = new CloneNotSupportedException();
e2.initCause(e);
throw e2;
}
}
}
class Employee extends SerialCloneable {
private String name;
private double salary;
private LocalDate hireDay; ...
}

执行

//7. 深拷贝
Employee harry = new Employee("Harry Hacker", 35000, 1989, 10, 1);
// clone harry
Employee harry2 = (Employee) harry.clone(); // mutate harry
harry.raiseSalary(10); // now harry and the clone are different
System.out.println(harry);
System.out.println(harry2);

结果

io.Employee[name=Harry Hacker,salary=38500.0,hireDay=1989-10-01]
io.Employee[name=Harry Hacker,salary=35000.0,hireDay=1989-10-01]

J2SE 8的输入输出--序列化的更多相关文章

  1. J2SE 8的输入输出--Path/Paths File/Files; FileSystems 类的用法

    Path的简单用法 //1. Path 正常用法 Path path = Paths.get("src/main/resource/zip"); logger.debug(path ...

  2. J2SE 8的输入输出--读取/写入文本文件和读取/写入二进制数据

    读取/写入文本文件 // 1. 文本输入 // (1) 短小文本直接转入字符串 String string = new String(Files.readAllBytes(Paths.get(&quo ...

  3. J2SE 8的输入输出--缓冲

    FileChannel带缓冲 //1. read the point location FileChannel channelRead = FileChannel.open(Paths.get(&qu ...

  4. Java深层复制方式

    为什么需要深层复制 Object 的 clone() 方法是浅层复制(但是 native 很高效).另外,Java 提供了数组和集合的复制方法,分别是 Arrays.copy() 和 Collecti ...

  5. flink1.10版本StreamGraph生成过程分析

    1.StreamGraph本质 本质就是按照用程序代码的执行顺序构建出来的用于向执行环境传输的流式图,并且可以支持可视化展示给用户的一种数据结构. 2.StreamGraph.StreamNode和S ...

  6. Spark:将RDD[List[String,List[Person]]]中的List[Person]通过spark api保存为hdfs文件时一直出现not serializable task,没办法找到"spark自定义Kryo序列化输入输出API"

    声明:本文转自<在Spark中自定义Kryo序列化输入输出API>   在Spark中内置支持两种系列化格式:(1).Java serialization:(2).Kryo seriali ...

  7. Java I/O流输入输出,序列化,NIO,NIO.2

    Java IO流 File类: File类是java.io包下代表和平台无关的文件和目录,File不能访问文件内容本身. File类基本操作: System.out.println("判断文 ...

  8. 在Spark中自定义Kryo序列化输入输出API(转)

    原文链接:在Spark中自定义Kryo序列化输入输出API 在Spark中内置支持两种系列化格式:(1).Java serialization:(2).Kryo serialization.在默认情况 ...

  9. Java对象序列化输入输出

    在网上看到一篇有关于对象序列化的代码,自己仿着写了把 在Java中,entity通过implements Serializable,然后使用ObjectInputStream和ObjectOutput ...

随机推荐

  1. JSON字符串-赋张最初接触后台从map转json的方法

    **************************************** json数组: *************************************************** ...

  2. tiny4412-Uboot启动分析

    一.从本质上将,引导转载程序至少应提供以下功能 (1)设置和初始化RAM (2)初始化一个串口 (3)检测机器类型(machine type) (4)设置内核标签列表(tag list) (5)调用内 ...

  3. dgraph 基本查询语法 二

    这部分主要是mutation 操作,(就是增加.删除操作) 参考git 项目 https://github.com/rongfengliang/dgraph-docker-compose-deploy ...

  4. Socket-Vs-WebSocket-TestTool

    项目地址 :  https://github.com/kelin-xycs/Socket-Vs-WebSocket-TestTool Socket-Vs-WebSocket-TestTool 一个用 ...

  5. FP-growth算法发现频繁项集(一)——构建FP树

    常见的挖掘频繁项集算法有两类,一类是Apriori算法,另一类是FP-growth.Apriori通过不断的构造候选集.筛选候选集挖掘出频繁项集,需要多次扫描原始数据,当原始数据较大时,磁盘I/O次数 ...

  6. revit API 生成墙图元

    由于Revit的版本问题,在网上找的生成墙图元的代码,在我机器上的Revit 2016中编译不能通过,通过多次调试,终于找到在revit 2016中使用API生成墙图元的代码,现在贴出来. 下面的代码 ...

  7. Mfs+drbd+keepalived实现mfs系统高可用

    http://blog.sina.com.cn/s/blog_53c654720102wo1k.html Moosefs分布式文件系统是一个易用的系统,但其只有在Pro版中提供了master的高可用方 ...

  8. 转jmeter --JDBC请求

    做JDBC请求,首先要了解这个JDBC对象是什么,然后寻找响应的数据库连接URL和数据库驱动. 数据库URL:jdbc:sqlserver://200.99.197.190:1433;database ...

  9. dzzoffice协同办公平台与onlyoffice在线协作平台安装与部署

    1.安装dzzoffice协同办公平台 DzzOffice是一套开源办公套件,适用于企业.团队搭建自己的 类似“Google企业应用套件”.“微软Office365”的企业协同办公平台. 官网地址:h ...

  10. iview-admin打包笔记

    在程序根目录右键打开cmd,输入 npm run build 这时就会进入打包的步骤,打包好之后就会在程序根目录出现一个dist的文件夹,里面有一个index.html文件和另一个dist的文件夹. ...