java Serializable接口没有功能,为什么会影响“ writeObject” /“ readObject”

时间:2018-11-22 15:33:53

标签: java serialization serializable

我检查了

的界面
Serializable

还没有函数定义,当我定义

private void readObject(ObjectOutputStream oos){
    System.out.println("readObject!!");
}
private void writeObject(ObjectOutputStream oos){
    System.out.println("writeObject!!");
}

类中的函数,在对象序列化时调用它们。

这对我来说很奇怪,如果接口定义了这两个函数,那么我应该重写它们以确保它们被调用。

但是在Serializable中,如果我定义了自己的“ writeObject” /“ readObject”,则编译器如何生成代码,以在序列化时调用它们?

我试图追加

@Override
在这两个函数的顶部加上

注释,编译器报告错误。

那么它是如何工作的,您能帮忙给出一些解释吗?

非常感谢!

1 个答案:

答案 0 :(得分:3)

java.io.Serializable是一个功能接口,因此这意味着它没有定义任何方法。如果您只想确保没有人会尝试修改覆盖的方法,则会添加@Override注释。 @Override上出现编译器错误的原因是Serializable中没有这样的方法,但是您可以在ObjectInputStream和ObjectOutputStream中找到它们(它们分别用作低级类FileInputStream和FileOutputStream)。 如果您真的想对列表进行序列化,则可以这样操作:

package Chaper8.IO;

import java.io.*;

import java.util.*;

public class Serialization_Deserialization {

public static void main(String [] args){

    /*
     *  try-catch with resources, JVM makes sure to close the resources after you've finished using it
     * much easier than using finally and getting an exception for each resource closed
     * 
     */
    try(FileOutputStream out = new FileOutputStream("C:\\Users\\Andrei\\Desktop\\Exemple\\worker.txt");
        ObjectOutputStream oos = new ObjectOutputStream(out);

        FileInputStream in = new FileInputStream("C:\\Users\\Andrei\\Desktop\\Exemple\\worker.txt");
        ObjectInputStream ois = new ObjectInputStream(in);){

        //instances of the Worker class
        Worker w1 = new Worker("Worker1", 123456 , 2000.5);
        Worker w2 = new Worker("Worker2", 765436, 1500.15);
        Worker w3 = new Worker("Worker3", 364582, 1700.45);
        Worker w4 = new Worker("Worker4", 878234, 2100.34);
        ArrayList<Worker> list = new ArrayList<>();

        //just adding the persons in the list
        list.add(w1);
        list.add(w2);
        list.add(w3);
        list.add(w4);


        System.out.println("Doing serialization");
        oos.writeObject(list);

        System.out.println("Doing deserialization");
        ois.readObject();

    }catch(IOException | ClassNotFoundException e){
            e.printStackTrace();
    }
}
} 

Worker.java

/*
 *  Worker class, basic type with variables, constructor, and toString() overridden
 *  Here I have implemented Serializable for the reason that I need to make sure that
 *  I will serialize the object within the class
 *
 *  Note that I used transient for id. transient is a special keyword which makes sure 
 * that id will not be serialized, used for security reasons.
 * 
 *  serialVersionUID is another variable which is used during deserialization 
 * to verify that the sender and receiver of a serialized object have loaded 
 * classes for that object that are compatible with respect to serialization. 
 *  Throws InvalidClassException if the object has a different serialVersionUID
 * than that of the corresponding sender's class.
 *  
 */

import java.io.*;
class Worker implements Serializable{

private static final long serialVersionUID = 1L;
private String name;
private transient int id;
private double wage;

public Worker(String name, int id, double wage){
    this.name = name;
    this.id = id;
    this.wage = wage;
}
public String toString(){
    return "Person with name " +
    name + " and with id " +
    id + " has a salary of " + wage + "$";
    }
}