java中transient关键字

一个对象只要实现了Serializable接口,该对象就可以被序列化。然而在实际开发过程中,常常会遇到这样的问题,该类有些属性需要序列化,其他属性不需要被序列化。例如一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及序列化)中被传输,这些信息对应的变量就可以加上transient关键字,这样变量的生命周期仅存在于调用者的内存中而不会被写到磁盘里持久化。

 

序列化与反序列化

持久化对象、RMI(远程方法调用)、在网络中传递对象时,会用到对象序列化。在序列化对象时,不仅会序列化当前对象本身,还会对该对象引用的其他对象也进行序列化。

序列化:把对象转换为字节序列的过程

反序列化:把字节序列恢复为对象的过程

java中只要实现了Serializable、Externalizable接口的类的对象就可被序列化。

 

实现Java对象序列化与反序列化的方法

方法一:若类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化

ObjectOutputStream采用默认的序列化方式,将对象的非transient的实例变量进行序列化。

ObjcetInputStream采用默认的反序列化方式,将对象的非transient的实例变量进行反序列化。

方法二:若类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStreamin)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。

ObjectOutputStream调用对象的writeObject(ObjectOutputStreamout)的方法进行序列化。

ObjectInputStream会调用对象的readObject(ObjectInputStreamin)的方法进行反序列化。

方法三:若类实现了Externalnalizable接口,且类必须实现readExternal(ObjectInputin)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。

ObjectOutputStream调用对象的writeExternal(ObjectOutput out))的方法进行序列化。

ObjectInputStream会调用对象的readExternal(ObjectInput in)的方法进行反序列化。

 

对象序列化和反序列化实例(方法一)+transient关键字:

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;
 
/**   
 * @Title: SerializableTest.java 
 * @author olive  
 * @date Feb 19, 2016 9:28:30 AM  
 * 序列化: 把对象转换为字节序列的过程
 * 反序列化: 把字节序列恢复为对象的过程
 */
public class SerializableTest implements Serializable{
    /**
     * serializable ID
     */
    private static final long serialVersionUID = -7873944822450384597L;
    private String username;
    private transient String psw;
    public SerializableTest(String username,String psw){
        this.username=username;
        this.psw=psw;
    }
     
    /**
     * @return the username
     */
    public String getUsername() {
        return username;
    }
 
    /**
     * @param username the username to set
     */
    public void setUsername(String username) {
        this.username = username;
    }
 
    /**
     * @return the psw
     */
    public String getPsw() {
        return psw;
    }
 
    /**
     * @param psw the psw to set
     */
    public void setPsw(String psw) {
        this.psw = psw;
    }
    public static void main(String[]args){
        SerializableTest a=new SerializableTest("mary","12345");
        String file="D:\\tmp.txt";
        try {
            System.out.println("username:"+a.getUsername()+" password:"+a.getPsw());
            // 使用ObjectOutputStream将对象SerializableTest序列化,并将其保存到文件中
            FileOutputStream fos=new FileOutputStream(file);
            ObjectOutputStream out=new ObjectOutputStream(fos);
            out.writeObject(a);
            out.flush();
            out.close();
            fos.close();
            // 使用ObjectInputStream将对象反序列化
            ObjectInputStream in=new ObjectInputStream(new FileInputStream("D:\\tmp.txt"));
            SerializableTest test=(SerializableTest)in.readObject();
            System.out.println("username:"+test.getUsername()+" password:"+test.getPsw());
            in.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}


输出:

1

2

3

username:mary password:12345

username:mary password:null

密码为null,说明反序列化没有从文件中得到该信息。

 

Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

 

参考:

http://www.cnblogs.com/lanxuezaipiao/p/3369962.html

http://blog.csdn.net/wangloveall/article/details/7992448

http://www.cnblogs.com/xdp-gacl/p/3777987.html

http://developer.51cto.com/art/201202/317181.htm

http://www.cnblogs.com/guanghuiqq/archive/2012/07/18/2597036.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值