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()