1. 程式人生 > >Java transient關鍵字使用小結

Java transient關鍵字使用小結

cti 說明 ioe void .class 類成員變量 使用 out main

1、transient關鍵字只能修飾變量,而不能修飾方法和類。註意,本地變量是不能被transient關鍵字修飾的。
2、被transient關鍵字修飾的變量不再能被序列化,一個靜態變量不管是否被transient修飾,均不能被序列化。
3、一旦變量被transient修飾,變量將不再是對象持久化的一部分,該變量內容在序列化後無法獲得訪問。也可以認為在將持久化的對象反序列化後,被transient修飾的變量將按照普通類成員變量一樣被初始化。

如下面的例子

package com.kkoolerter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

public class Main implements Serializable {

private static final long serialVersionUID = -5836283489677344417L;
private transient int classValue = 10;
private transient Date date = new Date();
private transient static int staticValue = 10;

public static void main(String[] args) throws Exception {
Main m = new Main();
m.classValue = 11;
Main.staticValue = 11;
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
new File("0xjh000")));
out.writeObject(m);

out.close();

ObjectInputStream in = new ObjectInputStream(new FileInputStream(
new File("0xjh000")));
Main m1 = (Main) in.readObject();
in.close();

System.out.println(m1.classValue);
System.out.println((m1.date == null ? "date is null"
: "date is not null"));
}

}

程序將輸出:
0
date is null

這就說明了一旦變量被transient修飾,變量將不再是對象持久化的一部分,該變量內容在序列化後無法獲得訪問。

思考一下下面的例子:
package com.kkoolerter;

import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class ExternalizableTest implements Externalizable {

private transient String content = "哈哈~我將會被序列化,不管我是是否被transient關鍵字修飾";

@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(content);
}

@Override
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
content = (String) in.readObject();
}

public static void main(String[] args) throws Exception {
ExternalizableTest et = new ExternalizableTest();
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
new File("ext0000")));
out.writeObject(et);

ObjectInput in = new ObjectInputStream(new FileInputStream(new File(
"ext0000")));
ExternalizableTest et1 = (ExternalizableTest) in.readObject();
System.out.println(et1.content);

out.close();
in.close();
}
}

程序運行後將輸出如下結果:
哈哈~我將會被序列化,不管我是是否被transient關鍵字修飾

這是為什麽呢,不是說類的變量被transient關鍵字修飾以後將不能序列化了嗎?
我們知道在Java中,對象的序列化可以通過實現兩種接口來實現,若操作的是一個Serializable對象,則所有的序列化將會自動進行,若操作的是 一個Externalizable對象,則沒有任何東西可以自動序列化,需要在writeExternal方法中進行手工指定所要序列化的變量,這與是否被transient修飾無關。因此第二個例子輸出的是變量content初始化的內容,而不是null。

Java transient關鍵字使用小結