跨平台的序列化和反序列化

一 java序列化操作的基本原理

1,什么序列化和反序列化

    serialization(序列化),是一种将对象按照一定规则生成出一连串有序的字符的过程。这个一连串有序的字符 可以是二进制,  xml,json,或特定的字符串 等等。

   Deserialization(反序列化)  将 一连串有序的字符 --》对象

2,什么情况下需要序列化

    a) 当你想把一个内存中对象保存到一个文件中或数据库中的时候(持久化)

   b)在跨平台的环境下,通过网络传输对象时(WebSerivce SOAP)

   c)当通过RMI传出对象的时候(仅限于java环境)

3,如何实现序列化

    需要实现序列化的类实现 serialization接口。 Serialization接口中无任何方法,所以我们可以理解为一个标记,表明这个类可以被序列化

4,Serializable的作用

     仅仅是个标记而已

5,序列化和反序列化例子

public class demo {
    //序列化Student对象至outFile文件
    public static void serialize(Object obj, String outFile) {
        try {
            ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(outFile));
            oos.writeObject(obj);
            oos.flush();
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //将outFile文件中的内容反序列化为Student对象
    public static Object deserialize(String readFile) {
        try {
            ObjectInputStream oos=new ObjectInputStream(new FileInputStream(readFile));
            Object obj=oos.readObject();
            oos.close();
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static void main(String[] args) {
        Student  stu=new Student("tengxvincent",18);
        String stuFileName="student.out";
        //serialize(stu,stuFileName);

        Student  student= (Student)deserialize(stuFileName);
        System.out.println(student);
    }
}

6,默认序列化机制

  

7,影响序列化

    7.1 transient关键字

      对于一些敏感的关键字(用户密码)可以用 transient 修饰该字段 不去序列化 

   7.2 静态变量是否能序列化 为什么?

      不能序列化

   7.3 writeObject()方法与readObject()方法

//jdk自动调用, 扩展序列化规则的一个方法
//打破serialization接口序列化规则
private void wirteObject(ObjectOutputStream out) throws IOException {
    // TODO Auto-generated method stub
    out.defaultWriteObject();
    out.writeInt(age);
}
private void readObject(ObjectInputStream in)throws IOException,ClassNotFoundException {
    // TODO Auto-generated method stub
    in.defaultReadObject();
    age=in.readInt();
}

   对于transient关键字修饰的字段 可以使用这两个方法 序列化


   7.4 Externalizable接口

/**
 *
 * 如果实现这个接口,jdk将不会调用默认的序列化规则,完全使用自定义的序列化规则
 */
public class Person implements Externalizable {

    private String name;

    transient private int age;

    //扩展序列化规则的方法
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        // TODO Auto-generated method stub
        name=(String)in.readObject();
        age=in.readInt();
    }
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        // TODO Auto-generated method stub
        out.writeObject(name);
        out.writeInt(age);
    }

  7.5 readResolve()方法

      当我们使用单例模式时,应该是期望这个类的实例是唯一的,但是如果该类是可实例化的,那么情况可能就不一样,

此时,我能可以使用 readResove()方法的实现,来确保在同一jvm中只有一个单例对象的引用

public class Message implements Serializable{
    private String name;
    private int age;

    private Message(String name,int age) {
        this.name=name;
        this.age=age;
    }

    /**
     * @return 获取一个单例对象
     */
    public static Message getInstance() {
        return InstanceHolder.instance;
    }

    private static class InstanceHolder{
        private static final Message instance=new Message("呵呵",18);
    }

    private Object readResolve() {
        return InstanceHolder.instance;
    }
}

8 序列化ID

  主要是针对跨平台,跨服务器,如果序列化ID不一致,会导致无法反序列化

9 序列化前和序列化后的对象的关系?

是==还是 equals  是浅克隆还是深克隆?


msgpack序列化与json序列化方式的比较





        


猜你喜欢

转载自blog.csdn.net/tengxvincent/article/details/80855961
今日推荐