1- 什么是序列化:序列化就是将对象 进行流化(转化为流的形式),并携带唯一标识 UID-序列化版本号,进行传输、通信。此外,你还可以持久化到文件(FileOutputStream流),数据库中(ORM思想)。
2- 为什么要序列化:类似Socket通信中,传输的数据以字节流的形式在服务器端和客户端之间传输通信,对象要是想在网络中进行传输通信话,或是进行读写操作,也要转化为流的形式,即需要序列化。
3- 怎么实现序列化:java实现序列化,即一个对象类 要实现Serializable接口。并建议赋予其序列化版本号UID值(原因在后面4讲到)。一方使用ObjectOutput接口的实现类ObjectOutputStream 提供的写方法:ObjectWrite将对象序列化到流,或持久化到本地文件,另一方使用ObjectInput接口的实现类ObjectInputStream提供的读方法:ObjectRead 从流中或是文件中反序列化为原对象。
4- 序列化要注意的问题:
|-要序列化的对象要实现Serializable接口,才能被编译器序列化。
|-要序列化的实体类要有唯一标识serialVersionUID,它是作为检验序列化的对象是否是同一个对象版本的唯一标识。如果对已序列化的对象再次进行修改,那么,这个标识值就会被编译器再次编译所改变。反序列化的话就会出现问题。所以,建议在实现序列化的时候,给出其serialVersionUID 的值。
对象序列化 实例-1:[Socket通信中对象序列化进行通信]
要序列化的对象类:Student
<span style="font-size:14px;">packagecom.entity;
importjava.io.Serializable;
publicclass Student implements Serializable{
private static final longserialVersionUID = 1L;
private String name;
private String sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result +age;
result = prime * result +((name == null) ? 0 : name.hashCode());
result = prime * result +((sex == null) ? 0 : sex.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() !=obj.getClass())
return false;
Student other = (Student)obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name !=null)
returnfalse;
} else if(!name.equals(other.name))
return false;
if (sex == null) {
if (other.sex !=null)
returnfalse;
} else if(!sex.equals(other.sex))
return false;
return true;
}
@Override
public String toString() {
return "Student[age=" + age + ", name=" + name + ", sex=" + sex +"]";
}
}</span>
客户端类:SocketClient
<span style="font-size:14px;">packagecom.client;
importjava.io.IOException;
importjava.io.ObjectOutputStream;
importjava.net.Socket;
importjava.net.UnknownHostException;
importcom.entity.Student;
publicclass SocketClient {
private String host;
private int port;
public SocketClient(String host, intport) {
this.host = host;
this.port = port;
}
public void client() throwsUnknownHostException, IOException {
Student s = newStudent();
s.setAge(20);
s.setName("luxury");
s.setSex("Man");
Socket socket = newSocket(host, port);
System.out.println("连接建立-");
ObjectOutputStreamoos = new ObjectOutputStream(socket
.getOutputStream());
oos.writeObject(s);//对象序列化
System.out.println("对象 发送完毕!");
oos.flush();
socket.close();
}
public static void main(String[] args)throws UnknownHostException,
IOException {
newSocketClient("localhost", 8009).client();
}
}</span>
服务器端类:SocketServer
<span style="font-size:14px;">packagecom.server;
importjava.io.IOException;
importjava.io.ObjectInputStream;
importjava.net.ServerSocket;
importjava.net.Socket;
importcom.entity.Student;
publicclass SocketServer {
private int port;
public SocketServer(int port){
this.port = port;
}
public void service() throwsIOException, ClassNotFoundException, InterruptedException{
ServerSocket server = newServerSocket(port);
Socket socket =server.accept();
System.out.println("有连接进来!");
// Thread.sleep(1000);
ObjectInputStream ois = newObjectInputStream(socket.getInputStream());
Student student =(Student)ois.readObject();//对象反序列化为原对象
System.out.println(student.getName()+"的信息如下 :"+student.toString());
ois.close();
socket.close();
}
public static void main(String[] args)throws IOException, ClassNotFoundException, InterruptedException {
newSocketServer(8009).service();
}
}</span>
Console结果:
客户端:
连接建立-
对象 发送完毕!
服务器端:
有连接进来!
luxury 的信息如下 : Student [age=20,name=luxury, sex=Man]
对象序列化 实例-2:对象序列化到文件
要序列化的对象类:Student
<span style="font-size:14px;">import java.io.Serializable;
/**
* 创建 Student 对象,并 实现 序列化 Serializable
* @author lu
*
*/
publicclass Student implements Serializable{
private static final longserialVersionUID = 2L;
private String name;
private int age;
private String grade;
private double 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 getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result +age;
result = prime * result +((grade == null) ? 0 : grade.hashCode());
result = prime * result +((name == null) ? 0 : name.hashCode());
long temp;
temp =Double.doubleToLongBits(salary);
result = prime * result +(int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() !=obj.getClass())
return false;
Student other = (Student)obj;
if (age != other.age)
return false;
if (grade == null) {
if (other.grade !=null)
returnfalse;
} else if(!grade.equals(other.grade))
return false;
if (name == null) {
if (other.name !=null)
returnfalse;
} else if(!name.equals(other.name))
return false;
if(Double.doubleToLongBits(salary) != Double
.doubleToLongBits(other.salary))
return false;
return true;
}
@Override
public String toString(){
return "name="+name+";age="+age+"; salary="+salary+";grade="+grade;
}
}</span>
序列化到文件和从文件反序列化类:
<span style="font-size:14px;">importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
/**
* 序列化 测试
* @author lu
*
*/
publicclass SerializableTest {
public static void main(String[] args){
objectIntoSerializable();
// serializableIntoObject();
}
/**
* 从 对象 实现序列化 到 文件
*/
public static voidobjectIntoSerializable() {
Student student = newStudent();
student.setAge(8);
student.setGrade("初三");
student.setName("小花");
student.setSalary(1000);
//ObjectOutputStream 类
ObjectOutputStream oos =null;
try {
oos = newObjectOutputStream( new FileOutputStream("R:\\Object.txt", true));
//将 对象 写入 字节流
oos.writeObject(student);
System.out.println("======写入OK=====");
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
oos.close();
} catch (IOExceptione) {
e.printStackTrace();
}
}
}
/**
* 从 文件 反序列化 到 对象
*/
public static voidserializableIntoObject() {
//ObjectInputStream 根据 字节流 重构对象
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(
newFileInputStream("R:\\Object.txt"));
Student s =(Student) ois.readObject();
System.out.println(s.toString());
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch(ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
ois.close();
} catch (IOExceptione) {
e.printStackTrace();
}
}
}
}</span>
Console结果:
序列化结果-
======写入OK=====
反序列化结果-
name=小花; age=8;salary=1000.0;grade=初三
Object.txt文件内容:
sr Student