Java transient使用小結

3509 ワード

1、transientキーワードは変数を修飾するだけで、方法とクラスを修飾することはできません.ローカル変数はtransientキーワードで修飾できないことに注意してください.2、transientキーワードで修飾された変数がシーケンス化されなくなり、
1つの静的変数は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でクラスをシーケンス化するには、次の2つの方法があります.
Serializableインタフェースを実現し、この場合、オブジェクトのシーケンス化と逆シーケンス化はjava自身のメカニズムで自動的に実現され、人為的に実現する必要はありません.
  • Externalizableインタフェースを実現し、writeExternal()とreadExternal()の2つの方法を実現し、自分のシーケンス化/逆シーケンス化操作を完成することができる.

  • Transient修飾の属性がシーケンス化されないという言葉は、上の1つ目の場合にのみ成立しますが、なぜでしょうか.
    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