transient 关键字

爱⌒轻易说出口 提交于 2019-12-26 01:12:43

一、transient的用途及使用方法

Java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是,用transient关键字标记的成员变量不参与序列化过程。

作用:
        Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。

用途

       当一个对象实现了Serilizable接口,这个对象就可以被序列化,只需要了解这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。而在开发过程中,我们可能要求:当对象被序列化时(写入字节序列到目标文件)时,有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
所以,transient的用途在于:阻止实例中那些用此关键字声明的变量持久化;当对象被反序列化时(从源文件读取字节序列进行重构),这样的实例变量值不会被持久化和恢复。例如,当反序列化对象——数据流(例如,文件)可能不存在时,原因是你的对象中存在类型为java.io.InputStream的变量,序列化时这些变量引用的输入流无法被打开。

public class TransientTest implements Serializable {
    private static final long serialVersionUID = 233858934995755239L;
    private String name1;
    private transient String name2;

    public TransientTest(String name1,String name2){
        this.name1 = name1;
        this.name2 = name2;
    }
    public String toString() {
        return String.format("TransientTest.toString(): name1=%s,name2=%s", name1, name2);
    }


    public static void main(String[] args) {
        String name1 = "常规属性", name2 = "transient修饰的属性";
        TransientTest test = new TransientTest(name1, name2);
        System.out.println("序列化前:" + test.toString());
        ObjectOutputStream outStream;
        ObjectInputStream inStream;
        String filePath = "E:\\bigdata\\test\\java\\transientTest.txt";
        try {
            outStream = new ObjectOutputStream(new FileOutputStream(filePath));
            outStream.writeObject(test);

            inStream = new ObjectInputStream(new FileInputStream(filePath));
            TransientTest readObject = (TransientTest) inStream.readObject();
            System.out.println("序列化后:" + readObject.toString());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

结果如下

序列化前:TransientTest.toString(): name1=常规属性,name2=transient修饰的属性
序列化后:TransientTest.toString(): name1=常规属性,name2=null

transient关键字标记的成员变量不参与序列化过程。

二、ArrayList中就有用到  transient 关键字

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     */
    transient Object[] elementData; // non-private to simplify nested class access

存储ArrayList元素的数组缓冲区。ArrayList的容量是此数组缓冲区的长度。 任何具有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的空ArrayList添加第一个元素时,将扩展为DEFAULT_CAPACITY。

 

其中,

a、DEFAULT_CAPACITY的值是10

    /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;

b、DEFAULTCAPACITY_EMPTY_ELEMENTDATA

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
共享的空数组实例,用于默认大小的空实例。 将此与 EMPTY_ELEMENTDATA 区别开来,当第一个元素被添加时,知道需要分配多大多少。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!