java 序列化教程

/ Java / 没有评论 / 1468浏览

java 序列化教程

序列化是将对象的状态信息转换为可存储或可传输的形式的过程,简而言之,把对象转换为字节数组的过程称之为对象的序列化。反序列化即序列化的逆过程。把字节数组恢复为对象的过程称为对象的反序列化。

序列化使用场景

评价序列化算法优劣的两个指标

java 序列化实现

先定义一个公共接口。

package com.xttblog.rpc.serialization.base;
// 业余草:www.xttblog.com
public interface MySerializer {
    /**
     * 序列化
     * @param obj
     * @param <T>
     * @return
     */
    <T> byte[] serialize(T obj);
    /**
     * 反序列化
     * @param data
     * @param clazz
     * @param <T>
     * @return
     */
    <T> T deserialize(byte[] data, Class<T> clazz);
}

使用 java 原生的方式实现该接口。

package com.xttblog.rpc.serialization;
import com.xttblog.rpc.serialization.base.JavaSerializerModel;
import com.xttblog.rpc.serialization.base.JavaSerializerModel2;
import com.xttblog.rpc.serialization.base.MySerializer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class JavaSerialization implements MySerializer{
    @Override
    public <T> byte[] serialize(T obj) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(obj);
            objectOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return byteArrayOutputStream.toByteArray();
    }
    @Override
    public <T> T deserialize(byte[] data, Class<T> clazz) {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
        try {
            ObjectInputStream objectInputStream= new ObjectInputStream(byteArrayInputStream);
            return (T) objectInputStream.readObject();
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
    public static void main(String[] args) {
        JavaSerialization javaSerialization = new JavaSerialization();
        JavaSerializerModel serializerModel = new JavaSerializerModel();
        JavaSerializerModel model = javaSerialization.deserialize(javaSerialization.serialize(serializerModel), JavaSerializerModel.class);
        System.out.println(model.getName());
        System.out.println(model.getPhone());
        System.out.println("------model2--------");
        JavaSerializerModel2 serializerModel2 = new JavaSerializerModel2();
        JavaSerializerModel2 model2 = javaSerialization.deserialize(javaSerialization.serialize(serializerModel2), JavaSerializerModel2.class);
        System.out.println(model2.getName());
        System.out.println(model2.getPhone());
    }
}

java 的序列化主要是通过 OutputStream 与 InputStream 来实现的,被序列化的类需要实现 java.io.Serializable 接口。

上述的实现代码是使用 java 进行序列化与反序列化的通用代码。

关于 java 序列化的其他知识点

序列化测试

JavaSerializerModel.java

package com.xttblog.rpc.serialization.base;
import java.io.Serializable;
public class JavaSerializerModel implements Serializable {
    private transient String name = "业余草";
    private String phone = "www.xttblog.com";
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
}

JavaSerializerModel2.java

package com.xttblog.rpc.serialization.base;
import java.io.Serializable;
public class JavaSerializerModel implements Serializable {
    private transient String name = "业余草";
    private String phone = "www.xttblog.com";
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
}

测试类 Main.java

public static void main(String[] args) {
	JavaSerialization javaSerialization = new JavaSerialization();
	JavaSerializerModel serializerModel = new JavaSerializerModel();
	JavaSerializerModel model = javaSerialization.deserialize(
		javaSerialization.serialize(serializerModel), JavaSerializerModel.class);
	System.out.println(model.getName());
	System.out.println(model.getPhone());
	System.out.println("------model2--------");
	JavaSerializerModel2 serializerModel2 = new JavaSerializerModel2();
	JavaSerializerModel2 model2 = javaSerialization.deserialize(
		javaSerialization.serialize(serializerModel2), JavaSerializerModel2.class);
	System.out.println(model2.getName());
	System.out.println(model2.getPhone());
}

测试结果:

null
www.xttblog.com
------model2--------
业余草
www.xttblog.com

可以看到,添加 writeObject() 与 readObject() 方法后,transient 字段也被正确序列化了。