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