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

Java transient使用小結

1、transient關鍵字只能修飾變數,而不能修飾方法和類。注意,本地變數是不能被transient關鍵字修飾的。

2、被transient關鍵字修飾的變數不再能被序列化,一個靜態變數不管是否被transient修飾,均不能被序列化

3、一旦變數被transient修飾,變數將不再是物件持久化的一部分,該變數內容在序列化後無法獲得訪問。也可以認為在將持久化的物件反序列化後,被transient修飾的變數將按照普通類成員變數一樣被初始化。

可看看下面的程式碼:

不加transient

package test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Testtransient {
	private final static String testPath = "D:/test"; 
	public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException{
		User user= new User("testUser","111111");
		System.out.println("原始資料:");
        System.out.println("userId: " + user.getUserName());
        System.out.println("password: " + user.getPassword());
        ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(testPath));
        os.writeObject(user);
        os.flush();
        os.close();
        ObjectInputStream is = new ObjectInputStream(new FileInputStream(testPath));
        User ruser = (User) is.readObject();
        is.close();
        System.out.println("從檔案恢復:");
        System.out.println("userId: " + ruser.getUserName());
        System.out.println("password: " + ruser.getPassword());
	}
}

class User implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String userName;
	private String password;
	public User(String username,String password){
		this.userName = username;
		this.password = password;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}
執行結果:
原始資料:
userId: testUser
password: 111111
從檔案恢復:
userId: testUser
password: 111111
注意下面:
class User implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String userName;
	private transient String password;
	public User(String username,String password){
		this.userName = username;
		this.password = password;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}
執行結果:
原始資料:
userId: testUser
password: 111111
從檔案恢復:
userId: testUser
password: null

transient修飾的屬性不能被序列化,但是這是有前提條件的。

我們知道在Java中要想讓一個類能夠實現序列化,可以通過如下兩種方法:

  • 實現Serializable介面,這種情況下,物件的序列化和反序列化都是java自己的機制自動實現的,不需要人為實現;
  • 實現Externalizable介面,可以實現writeExternal()和readExternal()這兩個方法,完成自己的序列化/反序列化操作;

transient修飾的屬性不能被序列化

這句話只在上面的第一種情況下成立,為什麼呢?

因為 如果實現的是Externalizable介面,序列化和反序列化都是自己控制的,不受transient的約束

參考:

http://qifuguang.me/2016/06/24/Java-transient%E5%85%B3%E9%94%AE%E5%AD%97%E8%A7%A3%E6%9E%90/

http://wujuxiang.blog.51cto.com/2250829/430211