package study.java.io.Serializable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* Java的串行化和transient关键字
*
* 【Java的串行化】
* Java的串行化,又叫做序列化和反序列化。
* 意思是指将一个类对象,转成01这样的字符串,或者将已经序列化的字符串转成对象。
* 普通的用法,如网络传输的时候,将对象序列化之后传送到服务器,在服务器端再解析成对象。
*
* 【transient关键字】
* Java语言的关键字,用来表示一个域不是该对象串行化的一部分。
* 当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,
* 然而非transient型的变量是被包括进去的。
* 例子:
* class A implements Serializable {
* private String name;
* transient private String address;
* }
* 对象A在串行化的时候,赋值name和address的话,实际上只有name的值被串行化了。
* 也就是说,虽然address也被赋值了,但是并没有保存在01字符串中。
* 反过来说,对于这个已经串行化的01字符串,转成对象的时候,name是有值的,address是无值的。
*
*
*
* @author paradisyer
*
*/
public class LoggingInfoMain {
/**
* 串行化transient关键字测试用例
*
* @param args
*/
public static void main(String[] args) {
// 新建一个对象,并给对象中的字符赋值
// uid="MIKE";
// pwd="MECHANICS";
LoggingInfo logInfo = new LoggingInfo("MIKE", "MECHANICS");
/* 输出结果:
* logon info:
* user: MIKE
* logging date: Fri Mar 02 15:38:06 JST 2012
* password: MECHANICS
*/
System.out.println(logInfo.toString());
try {
// 在内存中新建一个数据流对象,名字叫做"logInfo.out"
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("logInfo.out"));
// 把logInfo对象序列化,并写入到数据流对象"logInfo.out"中
o.writeObject(logInfo);
o.close();
} catch(Exception e) {
e.printStackTrace();
}
try {
// 新建一个读出流,把刚才建的数据流对象"logInfo.out"读出来。
ObjectInputStream in = new ObjectInputStream(new FileInputStream("logInfo.out"));
// 把数据流对象"logInfo.out"反序列化成LoggingInfo对象。
LoggingInfo logInfo1 = (LoggingInfo)in.readObject();
/* 输出结果:
* logon info:
* user: MIKE
* logging date: Fri Mar 02 15:38:06 JST 2012
* password: NOT SET
*/
// 注意这里password的值,因为定义成transient,所以在序列化的时候,并没有保存在内存中,所以读出来的时候是NULL
System.out.println(logInfo1.toString());
} catch(Exception e) {
e.printStackTrace();
}
/**************************************************华丽丽的分割线***************************************************/
// 下面的例子和上面的一样,唯一不同的是在GuestLoggingInfo类中加了默认构造函数。
// 为了测试反序列化的时候,是否走一个类的默认构造函数。
// 实际测试结果来看,反序列化的时候,仅仅是讲01字符串转成对象而已,
// 并没有走这个对象的构造函数方法。(没有给password赋值)
GuestLoggingInfo guestLogInfo = new GuestLoggingInfo("MIKE", "MECHANICS");
/* 输出结果:
* logon info:
* user: MIKE
* logging date: Fri Mar 02 15:38:06 JST 2012
* password: MECHANICS
*/
System.out.println(guestLogInfo.toString());
try {
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("GuestlogInfo.out"));
o.writeObject(guestLogInfo);
o.close();
} catch(Exception e) {
e.printStackTrace();
}
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("GuestlogInfo.out"));
GuestLoggingInfo guestLogInfo1 = (GuestLoggingInfo)in.readObject();
/* 输出结果:
* logon info:
* user: MIKE
* logging date: Fri Mar 02 15:38:06 JST 2012
* password: NOT SET
*/
System.out.println(guestLogInfo1.toString());
} catch(Exception e) {
e.printStackTrace();
}
/**************************************************华丽丽的分割线***************************************************/
// 下面的例子和上面的一样,唯一不同的是在GuestLoggingInfo类中加了默认构造函数。
// 为了测试反序列化的时候,是否走一个类的默认构造函数。
// 实际测试结果来看,反序列化的时候,仅仅是讲01字符串转成对象而已,
// 并没有走这个对象的构造函数方法。(没有给password赋值)
GuestLoggingInfo guestLogInfo2 = new GuestLoggingInfo();
/* 输出结果:
* logon info:
* user: guest
* logging date: Fri Mar 02 15:38:06 JST 2012
* password: guest
*/
System.out.println(guestLogInfo2.toString());
try {
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("GuestlogInfo.out"));
o.writeObject(guestLogInfo2);
o.close();
} catch(Exception e) {
e.printStackTrace();
}
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("GuestlogInfo.out"));
GuestLoggingInfo guestLogInfo3 = (GuestLoggingInfo)in.readObject();
/* 输出结果:
* logon info:
* user: guest
* logging date: Fri Mar 02 15:38:06 JST 2012
* password: NOT SET
*/
System.out.println(guestLogInfo3.toString());
} catch(Exception e) {
e.printStackTrace();
}
}
}
package study.java.io.Serializable;
import java.util.Date;
public class LoggingInfo implements java.io.Serializable {
private Date loggingDate = new Date();
private String uid;
private transient String pwd;
public LoggingInfo(String user, String password) {
uid = user;
pwd = password;
}
public String toString() {
String password = null;
if (pwd == null) {
password = "NOT SET";
} else {
password = pwd;
}
return "logon info:\n " + "user: " + uid +
"\n logging date: " + loggingDate.toString() +
"\n password: " + password;
}
}
package study.java.io.Serializable;
import java.util.Date;
public class GuestLoggingInfo implements java.io.Serializable{
private Date loggingDate = new Date();
private String uid;
private transient String pwd;
// private String pwd;
public GuestLoggingInfo() {
uid = "guest";
pwd = "guest";
}
public GuestLoggingInfo(String user, String password) {
uid = user;
pwd = password;
}
public String toString() {
String password = null;
if (pwd == null) {
password = "NOT SET";
} else {
password = pwd;
}
return "logon info:\n " + "user: " + uid +
"\n logging date: " + loggingDate.toString() +
"\n password: " + password;
}
}