Take advantage of "persistence"

Source: Internet
Author: User
Tags abstract getcolor serialization tostring advantage

A more tempting idea is to use serialization techniques to save some state information for a program so that it can be easily restored to its previous state. But before the concrete realization, some problems must be solved. If two objects have a handle to a third object, how do you serialize the two objects? If you restore them from the state after the serialization of two objects, will the handle of the third object only appear on one object? What happens if you serialize these two objects into separate files and then reassemble them in different parts of the code?
The following example shows a good description of the above issues:
 

: Myworld.java import java.io.*;

Import java.util.*;
  Class House implements Serializable {} class Animal implements Serializable {String name;
  House Preferredhouse; 
    Animal (String nm, house h) {name = NM;
  Preferredhouse = h;
  Public String toString () {return name + "[" + super.tostring () + "]," + preferredhouse + "\ n";
    } public class MyWorld {public static void main (string[] args) {House House = new House ();
    Vector animals = new vector ();
    Animals.addelement (New Animal ("Bosco the Dog", House));
    Animals.addelement (New Animal ("Ralph The Hamster", house));
    Animals.addelement (New Animal ("Fronk the Cat", House));

    System.out.println ("Animals:" + animals);
      try {bytearrayoutputstream buf1 = new Bytearrayoutputstream ();
      ObjectOutputStream O1 = new ObjectOutputStream (BUF1);
      O1.writeobject (animals); O1.writeobject (animals); Write a 2nd set//write To a different stream:bytearrayoutputstream buf2 = new Bytearrayoutputstream ();
      ObjectOutputStream O2 = new ObjectOutputStream (BUF2);
      O2.writeobject (animals);
            Now get them back:objectinputstream in1 = new ObjectInputStream (New Bytearrayinputstream (
      Buf1.tobytearray ())); ObjectInputStream in2 = new ObjectInputStream (New Bytearrayinputstream (Buf2.tobytearray ())
      );
      Vector animals1 = (vector) in1.readobject ();
      Vector animals2 = (vector) in1.readobject ();
      Vector animals3 = (vector) in2.readobject ();
      System.out.println ("ANIMALS1:" + animals1);
      System.out.println ("ANIMALS2:" + animals2);
    System.out.println ("ANIMALS3:" + ANIMALS3);
    catch (Exception e) {e.printstacktrace (); }
  }
} ///:~

One interesting thing here is that it's possible to use serialization of objects for a byte array, this enables a "full copy" of any Serializable (serializable) object (full replication means that the entire object network is replicated, not just the base object and its handle). The issue of replication will be fully covered in chapter 12th.
The Animal object contains a field of type House. In main (), a vector of these animal is created, serialized two times, and fed into two separate data streams. After the data has been reassembled and printed, you can see the following results (objects are in different memory locations each time they run, so there is a difference in the results of each run):

Animals: [Bosco the dog[animal@1cc76c], house@1cc769
, Ralph the hamster[animal@1cc76d], house@1cc769
, Fronk The cat[animal@1cc76e], house@1cc769
]
animals1: [Bosco the dog[animal@1cca0c], house@1cca16
, Ralph the HAMSTER[ANIMAL@1CCA17], House@1cca16
, Fronk the cat[animal@1cca1b], house@1cca16
]
animals2: [Bosco the DOG[ANIMAL@1CCA0C], House@1cca16
, Ralph the hamster[animal@1cca17], house@1cca16
, Fronk the cat[ ANIMAL@1CCA1B], house@1cca16
]
ANIMALS3: [Bosco the dog[animal@1cca52], house@1cca5c
, Ralph the HAMSTER[ANIMAL@1CCA5D], house@1cca5c
, Fronk the cat[animal@1cca61], house@1cca5c
]

Of course, we want the assembled objects to have addresses that are different from the original. Note, however, that the same address appears in ANIMALS1 and ANIMALS2, including shared, reference to house objects. On the other hand, when the ANIMALS3 is restored, the system has no way of knowing that the object in the other stream is the embodiment of the first stream object, so it produces a completely different network of objects.
As long as you serialize everything into a single data stream, you can recover the same network of objects that were written exactly as before, without inadvertently causing the object to repeat itself. Of course, between the time of writing the first and the last object, the state of the object can be changed, but that must be done explicitly by us-when serialized, the objects are written with any state of their time, including their connection to other objects.
If you want to save the system state, the safest approach is to serialize as a "microscopic" operation. If you serialize something, do some other work, serialize more, and so on, you will eventually be unable to safely save the system state. Instead, all objects that make up the system state are placed into a single collection, and the write of that collection is completed in one operation. As a result, the same method call is required to successfully recover.
The following example is a hypothetical computer-aided design (CAD) system, which is a good demonstration of this method. In addition, it introduces the problem of the static field--such as paying attention to the online documentation and discovering that class is "Serializable" (serializable), so you can save the static field simply by serializing the class object. This is a sensible way of doing things anyway.
 

: Cadstate.java//saving and restoring the state of A//pretend CAD system.
Import java.io.*;

Import java.util.*;
  Abstract class Shape implements Serializable {public static final int RED = 1, BLUE = 2, GREEN = 3;
  private int xpos, YPos, dimension;
  private static Random R = new Random ();
  private static int counter = 0;
  Abstract public void SetColor (int newcolor);
  Abstract public int getcolor ();
    Public Shape (int xval, int yval, int dim) {xpos = Xval;
    YPos = Yval;
  Dimension = Dim; 
      Public String toString () {return getclass (). toString () + "color[" + getcolor () + "] xpos[" + xpos +
  "] ypos[" + YPos + "] dim[" + Dimension + "]\n";
    public static Shape randomfactory () {int xval = r.nextint ()% 100;
    int yval = r.nextint ()% 100;
    int Dim = R.nextint ()% 100;
      Switch (counter++% 3) {default:case 0:return new Circle (Xval, Yval, dim);
 Case 1:return New Square (Xval, Yval, dim);     Case 2:return New Line (Xval, Yval, dim);
  }} class Circle extends Shape {private static int color = RED;
  Public Circle (int xval, int yval, int dim) {Super (Xval, Yval, dim);
  public void SetColor (int newcolor) {color = Newcolor;
  public int GetColor () {return color;
  Class Square extends Shape {private static int color;
    Public Square (int xval, int yval, int dim) {Super (Xval, Yval, dim);
  color = RED;
  public void SetColor (int newcolor) {color = Newcolor;
  public int GetColor () {return color;
  } class Line extends Shape {private static int color = RED;
  public static void Serializestaticstate (ObjectOutputStream os) throws IOException {os.writeint (color); public static void Deserializestaticstate (ObjectInputStream os) throws IOException {color = Os.readint ()
  ;
  Public line (int xval, int yval, int dim) {Super (Xval, Yval, dim); } public void SetColor(int newcolor)
  {color = Newcolor;
  public int GetColor () {return color; } public class Cadstate {public static void main (string[] args) throws Exception {Vector shapetypes, Sha
    pes
      if (Args.length = = 0) {shapetypes = new Vector ();
      Shapes = new Vector ();
      ADD handles to the class objects:shapeTypes.addElement (Circle.class);
      Shapetypes.addelement (Square.class);
      Shapetypes.addelement (Line.class);
      Make some shapes:for (int i = 0; i < i++) shapes.addelement (Shape.randomfactory ());
          Set all of the static colors to green:for (int i = 0; i < i++) ((Shape) Shapes.elementat (i))
      . SetColor (Shape.green); Save the state vector:objectoutputstream out = new ObjectOutputStream (New FileOutputStream ("C
      Adstate.out "));
      Out.writeobject (shapetypes);
      Line.serializestaticstate (out);
    Out.writeobject (shapes); } ElSE {//There ' s a command-line argument objectinputstream in = new ObjectInputStream (New Fileinpu
      Tstream (Args[0]));
      Read in the same order they were written:shapetypes = (Vector) in.readobject ();
      Line.deserializestaticstate (in);
    Shapes = (Vector) in.readobject ();
  }//Display the SHAPES:SYSTEM.OUT.PRINTLN (shapes); }
} ///:~

The

shape (geometry) class implements serializable (implements Serializable), so anything inherited from Shape is automatically serializable. Each shape contains data, and each derived shape class contains a special static field that determines the color of all those types of shape (such as placing a static field in the underlying class, resulting in only one field. Because the static field is not replicated in the derived class. You can overwrite methods in the underlying class to set colors for different types (static methods are not dynamically bound, so these are common methods). Each time the Randomfactory () method is invoked, it creates a different shape (the shape value takes a random value).
Circle (circles) and square (rectangles) are direct extensions to shape; the only difference is that Circle initializes the color when it is defined, and square is initialized in the builder. The question of line (straight lines) will be left to discuss later.
in Main (), one vector is used to hold the class object and the other to hold the shape. If you do not supply the corresponding command-line arguments, the Shapetypes Vector is created and the class object is added. Then create the Shapes Vector and add the Shape object. Next, all static color values are set to green, and everything is serialized to the file cadstate.out.
If a command-line argument is provided (assuming cadstate.out), the file is opened and used to recover the state of the program. In either case, the vector of the resulting shape will print out. The following lists the results of one run:
 

>java cadstate [Class Circle color[3] xpos[-51] ypos[-99] dim[38], class Square color[3] xpos[2] ypos[61] dim[-46], Class line color[3] xpos[51] ypos[73] dim[64], class Circle color[3] xpos[-70] ypos[1] dim[16], class Square color[3] XP OS[3] ypos[94] dim[-36], class line color[3] xpos[-84] ypos[-21] dim[-35], class Circle color[3] xpos[-75] ypos[-43] Dim [+], class Square color[3] xpos[81] ypos[30] dim[-45], class line color[3] xpos[-29] ypos[92] dim[17], class Circle Co LOR[3] xpos[17] ypos[90] dim[-76] >java cadstate cadstate.out [Class Circle color[1] xpos[-51] ypos[-99] dim[38], c Lass Square color[0] xpos[2] ypos[61] dim[-46], class line color[3] xpos[51] ypos[73] dim[64], class Circle color[1] XPo S[-70] ypos[1] dim[16], class Square color[0] xpos[3] ypos[94] dim[-36], class line color[3] xpos[-84] ypos[-21] dim[-35 ], class Circle color[1] xpos[-75] ypos[-43] dim[22], class Square color[0] xpos[81] ypos[30] dim[-45], class line Colo R[3] xpos[-29] ypos[92]DIM[17], class Circle color[1] xpos[17] ypos[90] dim[-76] 

As you can see, the values of Xpos,ypos and dim have been saved and restored successfully. However, there was a problem getting the static information. All "3" have entered, but did not come out normally. Circle has a 1 value (defined as red), and Square has a value of 0 (remember, they are initialized in the builder). It seems that static is not initialized at all! That's true--although class classes are "serializable", they don't work as we want them to. So if you want to serialize the static value, you have to do it yourself.
This is the purpose of the Serializestaticstate () and deserializestaticstate () two static methods in line. As you can see, both methods are explicitly invoked as part of the storage and recovery process (note that the order in which the serialization file is written and read back is not changed). So in order for Cadstate.java to work correctly, one of the following three methods must be used:
(1) Add a serializestaticstate () and Deserializestaticstate () to the Geometry shape.
(2) deletion of vector shapetypes and all code associated with it
(3) Add a call to the new serialization and undo serialization static method within a geometry shape
Another issue to note is security, because serialization processing also saves private data. If there are fields that need to be kept secret, mark them as transient. After this, however, a secure method of information preservation must be devised. That way, once you need to recover, you can reset those private variables.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.