目录
概念
序列化:对象->字节
反序列化:字节->对象
Demo
核心接口:
Serializable
核心类:
ObjectInputStream
、ObjectOutputStream
核心方法:
writeObject
、readObject
注意点
serialVersionUID
public class Person implements Serializable {
private static final long serialVersionUID = -7290089721196747652L;
private String name;
private int 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 "Person{" +
"name='" + name + '\'' +
", age=" + age
'}';
}
}
public class SerializeDemo {
public static void main(String [] args){
//序列化操作
SerializePerson();
//反序列化操作
DeSerializePerson();
}
public static void SerializePerson(){
try {
ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("person")));
Person person=new Person();
person.setName("c罗");
person.setAge(32);
oo.writeObject(person);
oo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void DeSerializePerson(){
try {
ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
Person person = (Person)oi.readObject();
System.out.println(person);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
序列化时类指定UID,反序列化时类没有指定UID(系统会给你自动指定一个UID)
两个UID不一致,会报错
serialVersionUID可以保证序列化和反序列化对象一致
静态变量不能被序列化
在刚才的Person对象中增加一个静态变量字段height
public static int height = 178;
public static void main(String [] args){
//序列化操作
SerializePerson();
Person.height=180;
//反序列化操作
Person person=DeSerializePerson();
System.out.println(person.height);
}
结果打印的不是序列化对象的height=178,而是我们设置的180
也就是说,静态变量不能被序列化
transient变量不能被序列化
在Person类中加一个变量transient修饰的sex
private transient String sex;
public class SerializeDemo3 {
public static void main(String [] args){
//序列化操作
SerializePerson();
//反序列化操作
Person person=DeSerializePerson();
System.out.println(person);
}
public static void SerializePerson(){
try {
ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("person"))); //默认在根目录
Person person=new Person();
person.setName("c罗");
person.setAge(32);
person.setSex("man");
oo.writeObject(person);
oo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Person DeSerializePerson(){
try {
ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
Person person = (Person)oi.readObject();
return person;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
sex打印为空,说明transient关键字指定的属性不参与序列化
父子类的序列化
如果父类没有实现序列化,而子类实现列序列化。那么父类中的成员没办法做序列化操作
public class SuperUser {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "SuperUser{" +
"name='" + name + '\'' +
'}';
}
}
public class User extends SuperUser implements Serializable {
private static final long serialVersionUID = -1290089721196747652L;
@Override
public String toString() {
return "User{} " + super.toString();
}
}
public class MyTest {
public static void main(String [] args){
//序列化操作
SerializeUser();
//反序列化操作
User user=DeSerializeUser();
System.out.println(user);
}
public static void SerializeUser(){
try {
ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("user"))); //默认在根目录
User user=new User();
user.setName("c罗");
oo.writeObject(user);
oo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static User DeSerializeUser(){
try {
ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("user")));
User user = (User)oi.readObject();
return user;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
name打印为null
说明父类属性没有参与序列化,因为父类没有实现Serializable
接口
把父类也实现Serializable就可以了
序列化的存储规则
public class SerializeDemo4 {
public static void main(String [] args){
//序列化操作
SerializePerson();
//反序列化操作
Person person=DeSerializePerson();
System.out.println(person);
}
public static void SerializePerson(){
try {
ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("person"))); //默认在根目录
ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
Person person=new Person();
person.setName("c罗");
person.setAge(32);
person.setSex("man");
oo.writeObject(person);
oo.flush();
System.out.println("第一次序列化成功,长度为"+new File("person").length());
Person person1=(Person)oi.readObject();
oo.writeObject(person);
oo.flush();
System.out.println("第二次序列化成功,长度为"+new File("person").length());
Person person2=(Person)oi.readObject();
oo.close();
System.out.println(person1==person2);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Person DeSerializePerson(){
try {
ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
Person person = (Person)oi.readObject();
return person;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
序列化实现深度克隆
public class Student implements Serializable {
private static final long serialVersionUID = -3330089721196747652L;
private String name;
private int age;
private Teacher teacher;
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 Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
//序列化的方式实现深度克隆
public Object deepClone() throws Exception{
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
return ois.readObject();
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", teacher=" + teacher +
'}';
}
}
public class Teacher implements Serializable {
private static final long serialVersionUID = -4330089021196747652L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}
public class cloneDemo {
public static void main(String []args)throws Exception{
Teacher teacher = new Teacher();
teacher.setName("a");
Student student=new Student();
student.setName("zhangsan");
student.setAge(18);
student.setTeacher(teacher);
System.out.println(student);
Student s = (Student)student.deepClone();
System.out.println(s);
System.out.println("student==s : "+(student==s)); //返回false表示不是指向同一个对象,即深度克隆
System.out.println("student.equals(s) : "+(student.equals(s)));
//修改s的老师的引用对象的属性值
s.getTeacher().setName("b");
System.out.println(student);
System.out.println(s);
}
}
主流的序列化技术
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pers.wmx.demo</groupId>
<artifactId>Serialize</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- spring默认的-->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<!-- 百度封装的 -->
<dependency>
<groupId>com.baidu</groupId>
<artifactId>jprotobuf</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.38</version>
</dependency>
</dependencies>
</project>
public class JsonDemo {
private static Person init(){
Person person = new Person();
person.setName("梅西");
person.setAge(30);
return person;
}
public static void main(String []args)throws Exception{
System.out.println("JackSon序列化...");
excuteWithJack();
System.out.println("FastJson序列化...");
excuteWithFastJson();
System.out.println("Protobuf序列化...");
excuteWithProtobuf();
System.out.println("Hessian序列化...");
excuteWithHessian();
}
//使用jackson序列化
private static void excuteWithJack() throws Exception{
Person person=init();
ObjectMapper mapper = new ObjectMapper();
byte [] writeBytes=null;
Long start=System.currentTimeMillis();
for(int i=0;i<10000;i++){
writeBytes=mapper.writeValueAsBytes(person);
}
System.out.println("序列化用时"+(System.currentTimeMillis()-start)+"ms");
System.out.println(writeBytes.length);
Person person1 = mapper.readValue(writeBytes,Person.class);
System.out.println(person1);
}
//使用fastjson序列化
private static void excuteWithFastJson() throws Exception{
Person person=init();
String text=null;
Long start=System.currentTimeMillis();
for(int i=0;i<10000;i++){
text=JSON.toJSONString(person);
}
System.out.println("序列化用时"+(System.currentTimeMillis()-start)+"ms");
System.out.println("text "+text);
System.out.println(text.getBytes().length);
Person person1 = JSON.parseObject(text,Person.class);
System.out.println("person1 "+person1);
}
//使用Protobuf序列化 性能高 字节数小,适合网络传输
private static void excuteWithProtobuf() throws Exception{
Person person=init();
Codec<Person> personCodec =ProtobufProxy.create(Person.class,false);
Long start=System.currentTimeMillis();
byte[] bytes=null;
for (int i = 0; i <10000 ; i++) {
bytes=personCodec.encode(person);
}
System.out.println("序列化用时"+(System.currentTimeMillis()-start)+"ms");
System.out.println(bytes.length);
Person person1 = personCodec.decode(bytes);
System.out.println(person1);
}
//使用Hessian序列化
private static void excuteWithHessian() throws Exception{
Person person=init();
ByteArrayOutputStream baos=new ByteArrayOutputStream();
HessianOutput ho=new HessianOutput(baos);
Long start=System.currentTimeMillis();
for (int i = 0; i <10000 ; i++) {
ho.writeObject(person);
}
System.out.println("序列化用时"+(System.currentTimeMillis()-start)+"ms");
System.out.println(baos.toByteArray().length);
ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
HessianInput hi=new HessianInput(bais);
Person person1 = (Person)hi.readObject();
System.out.println(person1);
}
}
本篇文章是复习序列化然后从我的CSDN迁过来的,哈哈…
说点什么
您将是第一位评论人!