Java Serializable接口总结

1. 介绍

序列化是把一个类实例(注意是实例)转换为byte stream,字节流的过程。反序列化则相反。换句话说,序列化是将Java对象转换为字节的静态流(序列),然后我们可以将其保存到数据库或通过网络传输。因为,类的实例是分配在内存的中的,类的实例在编程的时候,是一个高度抽象的东西,想要一个东西在网络报文中传输,需要把它转换成物理世界真实的东西,比如用字节流的方式。这个接口就是让我们去指定:如何把一个类转换为字节序列,比如说设置transient,或者实现writeObject或readObject来达到定制化的目的。
 
 
 

 2:序列化和反序列化

序列化过程是独立于实例(instance-independent);例如,我们可以在一个平台上序列化对象,在另一个平台上反序列化对象。序列化之后和序列化之前的对象是两个对象,只是拥有相同的数据罢了。

 

3:使用方法

1:Classes that are eligible for serialization need to implement a special marker interface, Serializable. 

Both ObjectInputStream and ObjectOutputStream are high level classes that extend java.io.InputStream and java.io.OutputStream, respectively. 

2:ObjectOutputStream can write primitive types and graphs of objects to an OutputStream as a stream of bytes. We can then read these streams using ObjectInputStream.

The most important method in ObjectOutputStream is:

public final void writeObject(Object o) throws IOException; 

This method takes a serializable object and converts it into a sequence (stream) of bytes. Similarly, the most important method in ObjectInputStream is:

public final Object readObject() 
  throws IOException, ClassNotFoundException;

This method can read a stream of bytes and convert it back into a Java object. It can then be cast back to the original object.

 

4:注意事项

1:静态变量属于类共有,不可以被序列化。

2:当一个类实现了java.io.Serializable接口时,它的所有子类也都是可序列化的。相反,当一个对象有另一个对象的引用时,这些对象必须单独实现Serializable接口,否则会抛出NotSerializableException:

3:如果可序列化对象中的一个字段由一个对象数组组成,那么所有这些对象也必须是可序列化的,否则将抛出NotSerializableException。

4:如果类中的一个实例字段是一个类类型,但又没有实现Serializale接口,但又想通过网络传输,让另一方也可以接收信息,那可以自定义两个方法

import java.io.*;

class Address{//没有实现Serializable
    String name = "";
    public Address(String name) {
        this.name = name;
    }
}

public class Employee implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    private transient Address address;

    public Employee(Address address) {
        this.address = address;
    }

    @Serial
    private void writeObject(ObjectOutputStream oos)//1
            throws IOException {
        oos.defaultWriteObject();
        oos.writeObject(address.name);//注意顺序
    }

    @Serial
    private void readObject(ObjectInputStream ois)//2
            throws ClassNotFoundException, IOException {
        ois.defaultReadObject();
        String addressName = (String) ois.readObject();//读出来的顺序和写进去的一致
        this.address = new Address(addressName);
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {


        Address a = new Address("xiejunyan");

        Employee e1 = new Employee(a);//

        FileOutputStream fileOutputStream
                = new FileOutputStream("yourfile2.txt");
        ObjectOutputStream objectOutputStream
                = new ObjectOutputStream(fileOutputStream);
        objectOutputStream.writeObject(e1);
        objectOutputStream.flush();
        objectOutputStream.close();

        FileInputStream fileInputStream
                = new FileInputStream("yourfile2.txt");
        ObjectInputStream objectInputStream
                = new ObjectInputStream(fileInputStream);

        Employee e2 = (Employee) objectInputStream.readObject();//
        objectInputStream.close();

        System.out.println("e1的hashcode: "+e1.hashCode());
        System.out.println("e2的hashcode: "+e2.hashCode());
        System.out.println("e1的address:  "+e1.address.name);
        System.out.println("e2的address:  "+e2.address.name);
    }
}



e1的hashcode: 1342443276
e2的hashcode: 6566818
e1的address: xiejunyan
e2的address: xiejunyan

 

 

 

 

 

 

 

站在巨人的肩膀上:https://www.baeldung.com/java-serialization

posted @ 2022-01-10 08:56  ou尼酱~~~  阅读(196)  评论(0)    收藏  举报