java 序列化
1. 什么是序列化?什么是反序列化?
@ 序列化: 将java对象 转换为 字节序列的过程 称为对象的序列化
@反序列化: 把字节序列恢复为对象的过程 称为对象的反序列化
为什么要序列化?
有一些对象 我们需要将他持久的保存起来---需要转换为字节 就是将内存里面的这些对象 变成一连串的字节,就是变成文件
2. 什么时候需要序列化?
当你把内存中的对象状态保存到一个文件中 或者数据库中的时候
当你想用套接字在网络上传送对象时
3. 实现Serializable接口
public class Person implements Serializable {
private static final long serialVersionUID = -5809782578272943999L;
Serialize 是什么?
这是IO存储中的一个概念。
计算机中所有的内容都是0或者1的数字。
这些数字按顺序排列,便可以表示计算机中的万事万物,当然Java的对象也不例外。
在内存中,无论如何表示,对我们的操作都没有影响,所以我们不必关心。
但是,当我们需要把对象存储到硬盘、数据库或其它相关介质时,我们就需要考虑这个表示格式或者转化方法。
Java的对象要如何转化为这0、1的序列呢?就是靠序列化,使用java.io.ObjectOutputStream类即可完成复杂的转化工作,
但ObjectOutputStream类可以支持的只有实现了Serializable接口的对象,
如果没有实现Serializable接口,则会抛出NotSerializableException。
你希望序列化的类中,常常可能参杂了一些临时性成员变量或者一些你并不希望它们被存储下来的属性,
这些成员变量或者属性,就需要用transient关键字修饰。
它们会在序列化时被忽略。当从存储介质中读取并还原成对象时,他们会被还原为属性的默认值(基本类型为0或false,对象为null)
JavaBean为什么要实现java.io.Serializable接口实现序列化?
客户端访问了某个能开启会话功能的资源,
web服务器就会创建一个与该客户端对应的HttpSession对象,
每个HttpSession对象都要站用一定的内存空间。
如果在某一时间段内访问站点的用户很多,
web服务器内存中就会积累大量的HttpSession对象,消耗大量的服务器内存,
即使用户已经离开或者关闭了浏览器,web服务器仍要保留与之对应的HttpSession对象,在他们超时之前,一直占用web服务器内存资源
4. 一个问题 实体类实现序列化接口,才能存到数据库吗?
一般的类型而言 String Date Integer 都是实现了Serializable接口的
父类实现了Serializable,子类不需要实现Serializable。即父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口
在hibernate里,并非所有的实体类必须实现序列化接口,因为在hibernate中我们通常是将基本类型的数值映射为数据库中的字段。而基础类型都实现了序列化接口(String也实现了)。
所以,只有在想将一个对象完整存进数据库(存储为二进制码),而不是将对象的属性分别存进数据库,读取时再重新构建的话,就可以不用实现序列化接口。实现了Serializable,可以方便保存数据。
public class Date implements java.io.Serializable
public abstract class Number implements java.io.Serializable
public final class Integer extends Number
2. 如何实现序列化
使用到JDK中关键类 ObjectOutputStream 和ObjectInputStream
ObjectOutputStream 类中:通过使用writeObject(Object object) 方法,将对象以二进制格式进行写入。
ObjectInputStream 类中:通过使用readObject()方法,从输入流中读取二进制流,转换成对象。
private transient String id
transient 的作用是用来屏蔽我们不希望进行序列化的变量,是对象在进行序列化和反序列话的过程中忽略该变量
Student.java
package com.fastjson.java;
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private transient String id;
private String age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id='" + id + '\'' +
", age='" + age + '\'' +
'}';
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Student(String name, String id) {
System.out.println("args Constructor");
this.name = name;
this.id = id;
}
public Student() {
System.out.println("none-arg Constructor");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
package com.fastjson.java;
import java.io.*;
class Main{
public static void main(String[]args){
File file=new File("E:/test.txt");
Student student=new Student("孙悟空","12");
try{
ObjectOutputStream outputStream=new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(student);
outputStream.close();
}catch(IOException e){
e.printStackTrace();
}
try{
ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream(file));
Student s=(Student)objectInputStream.readObject();
System.out.println(s.toString());
System.out.println(s.equals(student));
}catch(IOException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
}
总结:
java序列化是什么 ?
将一个实现类Serializable接口的对象转换成 一组 byte ,这样日后使用这个对象的时候,可以把这些byte数据恢复出来,重新 构建那个对象
为什么要进行序列化?
之所以要实现序列化,是因为他要实现两个重要的功能: java的远程方法调用(RMI)(Remote Method Invocation),能够像调用自己机器上的对象那样 去调用其他机器上的对象
和 对于javaBean的保存 ,Bean的状态信息必须要保存起来,供程序启动时调用