Java serialization--transient keyword and externalizable interface

Source: Internet
Author: User

Mention of Java serialization, I believe that everyone is not unfamiliar. When we serialize, we need to implement the serializable interface for the serialized class, so that when the class is serialized, all the fields are serialized by default. So when we're serializing a Java object, what if we don't want some of the fields in the object to be serialized (such as password fields)? See an example:

Import java.io.serializable;import java.util.date;public class logininfo implements  Serializable {    private static final long  serialversionuid = 8364988832581114038l;    private string username;     private transient string password;//note this key word   "Transient"     private Date loginDate;         //default public constructor    public logininfo ()  {         system.out.println ("Logininfo constructor");     }        //Non-Default constructor     Public logininfo (String username, string password)  {         this.username = username;        this.password = password;         logindate = new date ();     }     public string tostring ()  {         return  "Username="  + userName +  " password="                   + password +  ",  logindate= " + LOGINDATE;    }}

Test class:

Import java.io.fileinputstream;import java.io.fileoutputstream;import java.io.objectinputstream ;import java.io.objectoutputstream;public class test {    static  string filename =  "C:/x.file";     public static void main ( String[] args)  throws exception {        logininfo  info = new logininfo ("name",  "123");         SYSTEM.OUT.PRINTLN (Info);        //write         system.out.println ("Serialize object");         Objectoutputstream oos = new objectoutputstream (New fileoutputstream (fileName));         oos.writeobject (Info);         oos.close();        //read         System.out.println ("Deserialize object.");         ObjectInputStream ois = new  ObjectInputStream (New fileinputstream (fileName));         logininfo info2 =  (Logininfo) ois.readobject ();         Ois.close ();         system.out.println (Info2);     }}

Execution Result:

Username=name, password=123, logindate=wed Nov 16:41:49 CST 2015Serialize objectdeserialize object. Username=name, Password=null, logindate=wed 16:41:49 CST 2015

Another way to achieve this is to use less, that is, to implement the Externalizable interface without serializable. The externalizable interface has two methods that indicate which fields to deserialize when serializing, and which fields to deserialize when deserializing:

void Writeexternal (ObjectOutput out) throws Ioexception;void Readexternal (ObjectInput in) throws IOException, ClassNotFoundException;

     then has the following code:

Import java.io.externalizable;import java.io.ioexception;import java.io.objectinput;import  java.io.ObjectOutput;import java.util.Date;public class LoginInfo2 implements  Externalizable {    private static final long serialversionuid  = 8364988832581114038L;    private String userName;     private String password;    private Date loginDate;         //Default Public Constructor    public  LoginInfo2 ()  {        system.out.println ("logininfo  Constructor ");    }        //non-default  Constructor    public logininfo2 (String username, string password)  {        this.username = username;         This.password = password;        logindate = new  date ();     }    public string tostring ()  {         return  "Username="  + userName +  ",  Password= "                  + password +  ",  logindate="  + loginDate;    }      @Override     public void writeexternal (objectoutput out)  throws ioexception {        system.out.println (" Externalizable.writeexternal (objectoutput out)  is called ");         out.writeobject (Logindate);         out.writeutf (UserName);    }      @Override     public void readexternal (objectinput in)   throws ioexception, classnotfoundexception {         System.out.println ("externalizable.readexternal (objectinput in)  is called");         loginDate =  (Date) in.readobject ();         userName =  (String) In.readutf ();     }}

The test class remains the same except that the class name uses LoginInfo2. Here is the result of the execution:

Username=name, password=123, logindate=wed Nov 16:36:39 CST 2015Serialize objectexternalizable.writeexternal ( ObjectOutput out) is Calleddeserialize object. Logininfo Constructor//-------------------------Note this lineexternalizable.readexternal (ObjectInput on) is Calledusername=name, Password=null, logindate=wed 16:36:39 CST 2015

As you can see, the password after deserialization is still null.

It is important to note that for recovering a serializable object, the object is constructed entirely on the basis of its stored binary, without invoking the constructor. For a Externalizable object, the public's parameterless constructor will be called (so you can see the Logininfoconstructor line in the test results above) before calling Readexternal () Method . In the Externalizable interface documentation, the relevant description is also given:

When a Externalizable object is reconstructed, an instance was created using the public No-arg constructor and then the ReadE Xternal method called. Serializable objects is restored by reading them from an objectinputstream.

If there is no parameterless constructor for public, an error will be found. (The LoginInfo2 class's parameterless constructor is commented out, it will produce an error):

Username=name, password=123, logindate=wed Nov 17:03:24 CST 2015Serialize objectdeserialize object. Exception in thread "main" JAVA.IO.INVALIDCLASSEXCEPTION:LOGININFO2; No valid Constructorat java.io.objectstreamclass$exceptioninfo.newinvalidclassexception (ObjectStreamClass.java : @ java.io.ObjectStreamClass.checkDeserialize (objectstreamclass.java:768) at Java.io.ObjectInputStream.readOrdinaryObject (objectinputstream.java:1772) at Java.io.ObjectInputStream.readObject0 (objectinputstream.java:1350) at Java.io.ObjectInputStream.readObject ( objectinputstream.java:370) at Test2.main (test2.java:19)

So, what would be the effect of using the Externalizable interface with the transient keyword? We add the keyword transient to the password in LoginInfo2, and then modify the Writeexternal () and Readexternal () methods:

@Override public void Writeexternal (ObjectOutput out) throws IOException {Out.writeobject (logindate);        Out.writeutf (UserName);    Out.writeutf (password);  } @Override public void Readexternal (ObjectInput in) throws IOException, classnotfoundexception {logindate =        (Date) In.readobject ();        UserName = (String) In.readutf ();    Password = (String) In.readutf (); }

Execution Result:

Username=name, password=123, logindate=wed Nov 16:58:27 CST 2015Serialize objectdeserialize object. Logininfo Constructorusername=name, password=123, logindate=wed Nov 16:58:27 CST 2015

As you can see from the results, although the transient keyword is used on the password field, this is still not able to prevent serialization. Because it is not serialized and deserialized in the serializable way. This means:the transient keyword can only be used with the Serializable interface .

Java serialization--transient keyword and externalizable interface

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.