Home > Java > javaTutorial > body text

Java Basics - Serialization

PHP中文网
Release: 2017-07-09 18:13:10
Original
1472 people have browsed it

一、java中的序列化

当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。

对象的序列化主要有两种用途:

1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;

2) 在网络上传送对象的字节序列。

JDK类库中的序列化API

ObjectOutputStream //代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

ObjectInputStream  //代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

只有实现了Serializable和Externalizable接口的类的对象才能被序列化。

Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式
对象序列化包括如下步骤:

1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;

2) 通过对象输出流的writeObject()方法写对象。

对象反序列化的步骤如下:

1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;

2) 通过对象输入流的readObject()方法读取对象。

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Test3 {
            </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000">  IOException, ClassNotFoundException {
                </span><span style="color: #008000">/*</span><span style="color: #008000">ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("c:\\1.obj"));
                
                //序列化对象
                Person p=new Person(777,"我们要好好学习");
                
                out.writeObject("我是String类型的数据");  //写入String类型
                out.writeObject(new Date()); //写入日期类型
                out.writeObject(p); //写入自定义类型
                out.writeInt(123); //定入基本数据类型
                
                out.close();</span><span style="color: #008000">*/</span>
                
                <span style="color: #008000">//</span><span style="color: #008000">反序列化对象</span>
                ObjectInputStream in=<span style="color: #0000ff">new</span> ObjectInputStream(<span style="color: #0000ff">new</span> FileInputStream("c:\\1.obj"<span style="color: #000000">));
                
                System.out.println(</span>"obj1="+<span style="color: #000000">in.readObject());  
                System.out.println(</span>"obj2="+<span style="color: #000000">in.readObject());  
                System.out.println(</span>"obj3="+<span style="color: #000000">in.readObject());  
                System.out.println(</span>"obj4="+<span style="color: #000000">in.readInt());     
                
                in.close();
            }
        }</span>
Copy after login
<span style="color: #008000">//</span><span style="color: #008000">Serializable 是个空接口</span>
        <span style="color: #0000ff">class</span> Person <span style="color: #0000ff">implements</span><span style="color: #000000"> Serializable{
            </span><span style="color: #0000ff">int</span><span style="color: #000000"> age;
            String name;
            
            Person(</span><span style="color: #0000ff">int</span><span style="color: #000000"> age,String name){
                </span><span style="color: #0000ff">this</span>.age=<span style="color: #000000">age;
                </span><span style="color: #0000ff">this</span>.name=<span style="color: #000000">name;
            }
            
            </span><span style="color: #0000ff">public</span><span style="color: #000000"> String toString(){
                </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>.name+":"+<span style="color: #0000ff">this</span><span style="color: #000000">.age;
            }
        }</span>
Copy after login

2. Serializable interface and Externalizable interface (the following is the basic knowledge record)
1.Serializable

ObjectOutputStream can only serialize objects of classes with the Serializable interface.

By default, ObjectOutputStream is serialized in the default way. This serialization method only serializes the non-transient (transient, non-persistent) instance variables of the object, but does not serialize the transient instances of the object. variables, static variables will not be serialized.

When ObjectOutputStream is deserialized in the default way, it has the following characteristics:

1) If the class to which the object belongs in memory has not been loaded, then this class will be loaded and initialized first. If the corresponding class file does not exist in the classpath, ClassNotFoundException will be thrown;

2) No constructor method of the class will be called during deserialization.

If the user wants to control the serialization method of the class, the following forms of writeObject() and readObject() methods can be provided in the serializable class.

private void writeObject(java.io.ObjectOutputStream out) throws IOException

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

When ObjectOutputStream serializes a Person object, if the object has a writeObject() method, then this method will be executed, otherwise it will be serialized by default. In the writeObjectt() method of the object, you can first call the defaultWriteObject() method of ObjectOutputStream, so that the object output stream first performs the default serialization operation. The same can be said for deserialization, but this time the defaultReadObject() method is called.

Some objects contain some sensitive information, which should not be disclosed to the public. If they are serialized in the default way, their serialized data may be stolen by criminals when transmitted over the network. For this type of information, they can be encrypted and then serialized. During deserialization, they need to be decrypted and restored to the original information.

The default serialization method will serialize the entire object graph, which requires recursively traversing the object graph. If the object graph is complex, recursive traversal operations will consume a lot of space and time, and its internal data structure is a two-way list.

During application, if some member variables are changed to transient type (private transient int age), it will save space and time and improve the performance of serialization.

2.Externalizable

Inherits from the Serializable interface. If a class implements the Externalizable interface, then this class will completely control its own serialization behavior. The Externalizable interface declares two methods:

public void writeExternal(ObjectOutput out) throws IOException

public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException

The former is responsible for serialization operations, and the latter is responsible for deserialization operations.

When deserializing an object of a class that implements the Externalizable interface, /* will first call the class's constructor without parameters, which is different from the default deserialization method */

If you delete the constructor without parameters of the class, or set the access permission of the constructor to private, default or protected level,

Will throw java.io.InvalidException: no valid constructor exception.

3.serialVersionUID

ItSerialization compatibility of different versions of serializable classes. Any class that implements the Serializable interface has a static variable representing the serialization version identifier:

private static final long serialVersionUID;

The above serialVersionUID value is automatically generated by the Java runtime environment based on the internal details of the class. If the source code of a class is modified and then recompiled, the value of serialVersionUID of the newly generated class file may also change.

The default value of serialVersionUID of a class completely depends on the implementation of the Java compiler. For the same class, compiled with different Java compilers, it may result in different serialVersionUID, or it may be the same. In order to improve the independence and certainty of serialVersionUID, it is strongly recommended to explicitly define serialVersionUID in a serializable class and give it an explicit value. Explicitly defining serialVersionUID has two uses:

1) In some cases, it is hoped that different versions of the class are compatible with serialization, so it is necessary to ensure that different versions of the class have the same serialVersionUID;

2) In some cases, you do not want different versions of a class to be compatible with serialization, so you need to ensure that different versions of the class have different serialVersionUID

The above is the detailed content of Java Basics - Serialization. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template