Serializable Java serialization

Source: Internet
Author: User
Tags int size soap object serialization serialization sessions static class

It programmer development must-all kinds of resources download list, the most complete IT resources in history, personal collection summary.

The bean Serializable Interface interface allows the bean to serialize, turning it into a binary stream that can be saved for later use. When a bean is serialized to disk or anywhere else, its state is saved, and the value of the property does not change. In the bean's specification, the JSP does not require the bean to implement the serializable interface. However, if you want to control the serialization process of the components you create, or you want to serialize components that are not standard component extensions, you must understand the details of serialization and deserialization.

There are several reasons why you can refrigerate the beans for later use. Some servers support any long session lifetime by writing all of the sessions data (including beans) to disk, even if server downtime is not lost. When the server restarts, the serialized data is restored. For the same reason, in environments that support server clustering on heavily-loaded sites, many servers replicate sessions through serialization. If your bean does not support serialization, the server will not be able to save and transfer the classes correctly.

With the same strategy, you can choose to save the bean on disk or in the database for later use. For example, you might implement a customer's shopping cart as a bean and save it in a database during access.

If your bean requires special, complex initial settings, you can set the bean to be serialized and stored on disk. The "snapshot" of this bean can be used wherever it is needed, including in $#@60;jsp:usebean$#@62, with calls to the Beanname property.

The Beanname property in the $#@60;jsp:usebean$#@62 tab, which is used to instantiate a serialized bean instead of creating a completely new instance from a class. If the Bean has not yet been created, the Beanname property is passed to the Java.beans.Bean.instantiate () method, which is instantiated by the class loader. It first assumes that there is a serialized bean (with the extension. ser) and then activates it. If this operation fails, it instantiates a new instance.


Here's a brief introduction to this interface:

Objects can contain other objects, and other objects can contain other objects. The JAVA serialization can automatically handle nested objects. For a simple domain of an object, WriteObject () writes the value directly to the stream. When an object field is encountered, the WriteObject () is called again, and if the object is embedded in another object, then the WriteObject () is invoked until the object can be directly written to the inflow. What the programmer needs to do is to pass the object into the ObjectOutputStream writeobject () method, and the rest will be automatically completed by the system. The following example creates a Personaldata object that invokes the mine object. The code does this by outputting a string and mine object to a stream and depositing it in a file:

public class Personaldata implements Serializable {
public int ID
public int Yearofbirth;
public float yearlysalary;
}
Personaldata mine = new Personaldata (101, 1956, 46500.00);
FileOutputStream OutStream = new FileOutputStream ("Personaldata.ser");
ObjectOutputStream out = new ObjectOutputStream (OutStream);
Out.writeobject ("My personal Data"); Writes a string to the stream
Out.writeobject (mine); Writes this object to the stream
Out.close (); Clear and close the stream
...

A FileOutputStream object is created and passed to a objectoutputstream. When Out.writeobject () is invoked, this string and the mine object are added to a byte pair column that is stored in the file Serializ objects are personaldata.ser order.

You should note that the above class is the implemented Java.io.Serializable interface. Because it does not specify the method to implement, serializable is called "tagging interface", but it only "tags" its own object is a special type. Any object you want to serialize should implement this interface. This is a must. Otherwise, the flow technology will not work at all. For example, if you try to serialize an object that does not implement this interface, a notserializableexception will be generated.

Class enables its serialization functionality by implementing the Java.io.Serializable interface. A class that does not implement this interface will not be able to serialize or deserialize any of its states. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and is used only to identify serializable semantics.

Java object serialization allows you to convert an object that implements the serializable interface into a set of byte, so that when you use the object later, you can recover the byte data and reconstruct the object accordingly.

To serialize an object, you must first create a outputstream and then embed it in ObjectOutputStream. At this point, you can use the WriteObject () method to write the object to the OutputStream.

The WriteObject method is responsible for writing the state of the object of a particular class so that the corresponding ReadObject method can restore it. By calling Out.defaultwriteobject, you can invoke the default mechanism for fields that hold Object. The method itself does not need to involve states that belong to its superclass or subclass. States are saved by writing each field to ObjectOutputStream by using the WriteObject method or by using a method supported by DataOutput for the base data type.

When you read, you have to embed the inputstream inside the ObjectInputStream, and then call the ReadObject () method. But this read out, is only an object reference, so before using, still have to pass first. The ReadObject method is responsible for reading and restoring class fields from the stream. It can call the In.defaultreadobject to invoke the default mechanism to restore the non-static and non transient fields of the object.

The Defaultreadobject method uses the information in the stream to allocate fields in the stream that are saved by the corresponding named fields in the current object. This is used to handle the situation where new fields need to be added after class development. The method itself does not need to involve states that belong to its superclass or subclass. States are saved by writing each field to ObjectOutputStream by using the WriteObject method or by using a method supported by DataOutput for the base data type.

Look at a:


Import java.io. * ;

Class Tree implements Java.io.Serializable {
Public tree left;
The public is right;
public int id;
public int level;

private static int count = 0;

     public  Tree (int  depth)    {
         id  =  count + +;
        level  =  depth;
         if  (depth  >   0)    {
& nbsp;           left  =   new  tree (depth-1) ;
            right  =   new  Tree ( DEPTH-1);
       } 
   } 

public void print (int levels) {
for (int i = 0; i < level; I + +)
System.out.print ("");
System.out.println ("node" + ID);

If (level <= levels && left!= null)
Left.print (levels);

If (level <= levels && right!= null)
Right.print (levels);
}


public static void Main (String argv[]) {

try {
/**//* Creates a file to write to the serialization tree. */
FileOutputStream ostream = new FileOutputStream ("tree.tmp");
/**//* Create output stream * *
ObjectOutputStream p = new ObjectOutputStream (ostream);

/**//* Create a two-layer tree. */
Tree base = new Tree (2);

The

            p.writeobject (base); //  writes the tree to the stream.  
             p.writeobject ("LiLy is the Southland");
            P.flush ();
            ostream.close ();       Close the file.  
 
             /**//*  Opens the file and sets the object to be read from.   */ 
            FileInputStream IStream   =   new  fileinputstream ("tree.tmp");
            ObjectInputStream q  =   New   ObjectInputStream (IStream);

/**//* Read the tree object, and all subtree * *
Tree New_tree = (tree) q.readobject ();

New_tree.print (2); Print out the top 2 level of the tree structure
String name = (string) q.readobject ();
System.out.println ("n" + name);
catch (Exception ex) {
Ex.printstacktrace ();
}
}
}
The final results are as follows:

Node 0
Node 1
Node 2
Node 3
Node 4
Node 5
Node 6

LiLy is the Southland

You can see the sequence between WriteObject and ReadObject at the time of serialization. ReadObject the first write object read out. In terms of data structure, let's call it advanced first.

When serializing, there are a few things to note:
1: When an object is serialized, only non-static member variables of the object are saved, and no member methods and static member variables can be saved.
2: If an object's member variable is an object, then the data member of the object is also saved.
3: If a serializable object contains a reference to an object that is not serializable, the entire serialization operation will fail and a notserializableexception will be thrown. We can mark this reference as transient, so the object can still be serialized

And when we serialize an object, we tend to serialize the entire object, such as some of the data in the class are sensitive, do not want serialization, a method can be identified with transient, and another method can be overridden in a class

private void ReadObject (Java.io.ObjectInputStream stream)
Throws IOException, ClassNotFoundException;
private void WriteObject (Java.io.ObjectOutputStream stream)
Throws IOException

These two methods.
Example:

Import java.io. * ;

Class Objectserialtest
{
public static void Main (string[] args) throws Exception
{
Employee e1 = new Employee ("Zhangsan", 25, 3000.50);
Employee E2 = new Employee ("Lisi", 24, 3200.40);
Employee E3 = new Employee ("Wangwu", 27, 3800.55);

FileOutputStream fos = new FileOutputStream ("Employee.txt");
ObjectOutputStream oos = new ObjectOutputStream (FOS);
Oos.writeobject (E1);
Oos.writeobject (E2);
Oos.writeobject (E3);
Oos.close ();

FileInputStream fis = new FileInputStream ("Employee.txt");
ObjectInputStream ois = new ObjectInputStream (FIS);
Employee e;
for (int i = 0; i < 3; i + +)
{
E = (Employee) ois.readobject ();
System.out.println (E.name + ":" + E.age + ":" + e.salary);
}
Ois.close ();
}
}

Class Employee implements Serializable
{
String name;
int age;
Double salary;
Transient thread t = new thread ();
Public Employee (String name, int age, double salary)
{
this. Name = name;
this. Age = age;
this. Salary = salary;
}
private void WriteObject (Java.io.ObjectOutputStream oos) throws IOException
{
Oos.writeint (age);
OOS.WRITEUTF (name);
System.out.println ("Write Object");
}
private void ReadObject (Java.io.ObjectInputStream ois) throws IOException
{
Age = Ois.readint ();
Name = Ois.readutf ();
System.out.println ("Read Object");
}

}
--(Add on 2006/6/28)

References: JDK1.5 API DOC Sun Xin Teacher Information

1, the implementation of serializable back to cause the release of the API difficult to change, and make package-private and private
These two better drums are not guaranteed to be sealed.
2, serializable will generate a serial number for each class, generated based on the class name, class implementation of the interface name,
Public and protected methods, so as long as you accidentally change a already publish API, and not from
Define a long type field called Serialversionuid, even if just add a getxx, it will
Let you read the original serialization to the file of the things you can't read (do not know why the method name is included in.) )
3, without the constructor to use serializable can construct objects, it seems not reasonable, this is called
Extralinguistic mechanism, so when implementing serializable you should pay attention to maintaining the dimension in the constructor
The invariant state of being held
4, increased the release of the new version of the class when the test burden
After version 5 and 1.4, JavaBeans's persistence takes the xml-based mechanism and no longer requires serializable
6, designed to be inherited classes, as far as possible not to implement serializable, used to be inherited interface also do not
Inherit serializable. But if the parent class does not implement the Serializable interface, it is difficult for subclasses to implement it, especially
It is not possible for a parent class to have no access to a constructor that contains no parameters. So once you decide not to implement
Serializable interface and when the class is used to inherit, remember to provide a parameterless constructor
7, the internal class or do not implement serializable good, unless it is static, (I also feel that the internal class is not suitable for
Used to do this kind of work)
8. Use a custom serialization method
Take a look at the following example of saving a two-way list:

public class Stringlist implements Serializable
{
? private int size = 0;
? private Entry head = NULL;
?
? private static class Entry implements Serializable
? {
? String data;
? Entry Next;
? Entry previous;
?}
?...//remainder ommitted
}


This causes each element of the linked list and the relationship between the elements (the connection between the two-way linked lists)
Are saved, a better approach is to provide a custom serialization as follows:

String List with a resonable custom serialized form
Class Stringlist implements Serializable
{
? private transient int size = 0;?????? !transient
? Private transient Entry head = NULL;? !transient
?
? No longer serializable!
? private Static Class Entry
? {
??? String data;
??? Entry Next;
??? Entry previous;
? }
?
? Appends the specified string to the list
? public void Add (String s) {/*...*/};
?
? /**
?? * Serialize this stringlist instance
?? * @author Yuchifang
?? * @serialData the size of the list (the number of strings
* It contains) is emitted (int.), in the proper sequence
?? */
? private void WriteObject (ObjectOutputStream s)
Throws IOException
? {
??? S.defaultwriteobject ();
??? S.writeint (size);
??? Write out all elements in the proper order
??? for (Entry e = head; e!= null; e = e.next)
????? S.writeobject (E.data);
? }
?
? private void ReadObject (ObjectInputStream s)
Throws IOException, ClassNotFoundException
? {
??? int numelements = S.readint ();
???
??? Read in all elements andd insert them in list
??? for (int i = 0; i < numelements; i++)
????? Add ((String) s.readobject ());
? }
? ... remainder omitted
}


9, regardless of what serialization form you choose, declare an explicit UID:

Private static final long serialversionuid = Randomlongvalue;

10, does not need to serialize the thing to use transient to drop it, don't keep everything

11, Writeobject/readobject overload to achieve better serialization

Readresolve with Writereplace overload to complete better maintenance invariant controllers

MarshalByRefObject and Serializable

Recently looking at the Web sevice aspects of things, by the way read the serialization, understand a lot of AH:

Classes derived from MarshalByRefObject and those with [Serializable] can be passed across the application domain as parameters.
Classes derived from MarshalByRefObject are marshaled by reference, with a class of [Serializable] flags, marshaled by value.
If this class derives from MarshalByRefObject, there are also [Serializable] flags marshaled by reference.

There are 3 types of serialization:

Serialized in XML format:
In WebService, it's the case that you write a Web method and pass a custom class as a parameter. The system will help you fix it, convert the custom class to the default XML format.
Serialized into 2:
To add a [Serializable] flag, you can serialize both private and public variables.
Serialized as SOAP format:
You need to implement the ISerializable interface, define the serialization function ISerializable.GetObjectData, and restore the serialized constructor.
Sample for a SOAP parameter class:
[Serializable]
public class Serialze:iserializable
{
The serialization function, which is called by the SoapFormatter during serialization.
void ISerializable.GetObjectData (SerializationInfo info, StreamingContext
Ctxt)
{
Add each field to the SerializationInfo object
Info. AddValue ("UserName", UserName);
Info. AddValue ("UserID", UserID);
}

       //restore serialization constructors, called by SoapFormatter during the restore serialization process
         public Serialze (SerializationInfo info, StreamingContext ctxt)
         {
           //from SerializationInfo In the
            UserName = (string) Info of the various fields in the restore serialization in the GetValue ("UserName", typeof (String));
            UserID = (int) info. GetValue ("UserID", typeof (int));
       }
 
        public Serialze ()
         {}

        public string UserName;
        public int UserID;
   }
Yes, if the session is to be saved to the database, you must add the serializable tag ~

Related Article

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.