Java自定义序列化

示例

在此示例中,我们要创建一个将生成并输出到控制台的类,该类是在初始化期间作为参数传递的两个整数范围之间的随机数。

    public class SimpleRangeRandom implements Runnable {
    private int min;
    private int max;

    private Thread thread;

    public SimpleRangeRandom(int min, int max){
       this.min= min;
       this.max= max;
        thread = new Thread(this);
        thread.start();
    }

    @Override
 private void WriteObject(ObjectOutputStreamout) throws IO Exception;
    private void ReadObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
    public void run() {
        while(true) {
            Random rand = new Random();
            System.out.println("Thread: " + thread.getId() + " Random:" + rand.nextInt(max - min));
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    }

现在,如果要使此类可序列化,则将存在一些问题。线程是某些不可序列化的系统级类之一。因此,我们需要将线程声明为transient。通过这样做,我们将能够序列化此类的对象,但是仍然会遇到问题。正如您在构造函数中看到的那样,我们设置了随机化器的最小值和最大值,然后启动了负责生成和打印随机值的线程。因此,通过调用readObject()构造函数恢复持久对象时,由于不会创建新对象,因此构造函数将不会再次运行。在这种情况下,我们需要通过在类内部提供两个方法来开发自定义序列化。这些方法是:

private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

因此,通过在中添加实现,readObject()我们可以启动和启动线程:

class RangeRandom implements Serializable, Runnable {

private int min;
private int max;

private transient Thread thread;
//瞬变应该是无法序列化的任何字段e.gThread或您不想序列化的任何字段

public RangeRandom(int min, int max){
   this.min= min;
   this.max= max;
    thread = new Thread(this);
    thread.start();
}

@Override
public void run() {
    while(true) {
        Random rand = new Random();
        System.out.println("Thread: " + thread.getId() + " Random:" + rand.nextInt(max - min));
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    thread = new Thread(this);
    thread.start();
}
}

这是我们示例的主要内容:

public class Main {
public static void main(String[] args) {
    System.out.println("Hello");
    RangeRandom rangeRandom = new RangeRandom(1,10);

    FileOutputStream fos = null;
    ObjectOutputStream out = null;
    try
    {
        fos = new FileOutputStream("test");
        out = new ObjectOutputStream(fos);
        out.writeObject(rangeRandom);
        out.close();
    }
    catch(IOException ex)
    {
        ex.printStackTrace();
    }


    RangeRandom rangeRandom2 = null;
       FileInputStream fis = null;
       ObjectInputStream in = null;
       try
       {
             fis = new FileInputStream("test");
             in = new ObjectInputStream(fis);
           rangeRandom2 = (RangeRandom)in.readObject();
             in.close();
           }
       catch(IOException ex)
       {
             ex.printStackTrace();
           }
       catch(ClassNotFoundException ex)
       {
             ex.printStackTrace();
           }

}
}

如果运行main,则将为每个RangeRandom实例运行两个线程,这是因为该方法现在同时在构造函数和。Thread.start()readObject()