Java关键字(一) —— transient

在讨论transient之前,有必要先搞清楚Java中序列化的含义;

Java中对象的序列化指的是将对象转换成以字节序列的形式来表示,这些字节序列包含了对象的数据和信息,一个序列化后的对象可以被写到数据库或文件中,也可用于网络传输,一般当我们使用缓存cache(内存空间不够有可能会本地存储到硬盘)或远程调用rpc(网络传输)的时候,经常需要让我们的实体类实现Serializable接口,目的就是为了让其可序列化。

当然,序列化后的最终目的是为了反序列化,恢复成原先的Java对象,要不然序列化后干嘛呢,所以序列化后的字节序列都是可以恢复成Java对象的,这个过程就是反序列化。

Java中transient关键字的作用,简单地说,就是让某些被修饰的成员属性变量不被序列化,这一看好像很好理解,就是不被序列化,那么什么情况下,一个对象的某些字段不需要被序列化呢?如果有如下情况,可以考虑使用关键字transient修饰:

1、类中的字段值可以根据其它字段推导出来,如一个长方形类有三个属性:长度、宽度、面积(示例而已,一般不会这样设计),那么在序列化的时候,面积这个属性就没必要被序列化了;

2、其它,看具体业务需求;

P.S. 集合类中涉及的不需要序列化的成员属性
1).ArrayList

private transient Object[] elementData; //保存ArrayList中数据的数组

elementData 是"Object[]类型的数组",它保存了添加到ArrayList中的元素。实际上,elementData是个动态数组,我们能通过构造函数 ArrayList(int initialCapacity)来执行它的初始容量为initialCapacity;如果通过不含参数的构造函数ArrayList()来创建ArrayList,则elementData的容量默认是10。elementData数组的大小会根据ArrayList容量的增长而动态的增长,具体的增长方式,请参考源码分析中的ensureCapacity()函数。
---- ArrayList中有这样两个方法 writeObject() 和 readObject()

2).AbstractList

protected transient int modCount = 0;

package collectionstudy;

import java.io.*;

/**
 * @ClassName: Rectangle
 * @Author sandy.n.hao
 * @Date: 2018/11/30
 * @Version v1.0.0
 * @Description: //TODO
 */

public class Rectangle implements Serializable {

    private int length = 0;
    private int width = 0;

    private transient int area;

    public  Rectangle(int length, int width){
        this.length = length;
        this.width = width;
    }

    public void setArea() {
        this.area = this.length * this.width;
    }

    @Override
    public String toString() {
        return "Rectangle{" +
                "length=" + length +
                ", width=" + width +
                ", area=" + area +
                '}';
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        Rectangle rectangle = new Rectangle(3,7);

        //原始对象
        System.out.println("1.原始对象:"+ rectangle);
        rectangle.setArea();

        //序列化-输出
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("rectangle"));
        objectOutputStream.writeObject(rectangle);
        objectOutputStream.close();

        //反序列化-输入
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("rectangle"));
        Rectangle rectangle_clone = (Rectangle) objectInputStream.readObject();

        //复原对象
        System.out.println("2.原始对象:"+ rectangle);
        System.out.println("3.拷贝对象:"+ rectangle_clone);
    }
}

程序运行结果:

1.原始对象:Rectangle{length=3, width=7, area=0}
2.原始对象:Rectangle{length=3, width=7, area=21}
3.拷贝对象:Rectangle{length=3, width=7, area=0}

你可能感兴趣的:(Java关键字(一) —— transient)