Java中的transient关键字

transient关键字用于阻止序列化过程将特定属性持久化。序列化时,被transient修饰的变量不会被保存。静态变量不论是否被transient修饰,都不会被序列化,因为它们属于类而非对象。序列化主要是为了存储对象状态,但transient变量的生命周期仅限内存,不会写入磁盘。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

transient关键字简述

将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会被序列化。
关于序列化:
Java序列化提供两种方式。

  • 一种是实现Serializable接口
  • 另一种是实现Exteranlizable接口。 需要重写writeExternal和readExternal方法,它的效率比Serializable高一些,并且可以决定哪些属性需要序列化(即使是transient修饰的),但是对大量对象,或者重复对象,则效率低。

代码:

public class TransientTest {

    public static void main(String[] args) {
        //序列化Person对象,再反序列化读取
        Person person = new Person("张三", 22);
        System.out.println("序列化前:");
        System.out.println(person);
        System.out.println(person.getOCCUPATION());
        System.out.println(person.getTEST());

        ByteOutputStream bos = null;
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
            //序列化person
            bos = new ByteOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(person);
            oos.flush();
            //序列化后,改变被static修饰的成员变量、被static transient修饰的成员变量
            person.setOCCUPATION("厨师");
            person.setTEST("测试");
            //反序列化person
            ois = new ObjectInputStream(bos.newInputStream());
            Person deserialization = (Person) ois.readObject();
            System.out.println("反序列化后");
            System.out.println(deserialization);
            System.out.println(deserialization.getOCCUPATION());
            System.out.println(deserialization.getTEST());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class Person implements Serializable {

    private String name;
    private transient int age;
    public static String OCCUPATION = "程序猿";
    public static transient String TEST = "test";

    public Person() {}
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getOCCUPATION() {
        return OCCUPATION;
    }

    public void setOCCUPATION(String OCCUPATION) {
        Person.OCCUPATION = OCCUPATION;
    }

    public String getTEST() {
        return TEST;
    }

    public void setTEST(String TEST) {
        Person.TEST = TEST;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


运行结果:
序列化前:
Person{name=‘张三’, age=22}
程序猿
test
反序列化后
Person{name=‘张三’, age=0}
厨师
测试
简析:
可以看到加了transient关键字的int类型的age并没有被序列化成功,而是默认的值0。

深入transien关键字

transient的底层实现原理

java的serialization提供了一个非常棒的存储对象状态的机制,serialization就是把对象的状态存储到硬盘上 去,等需要的时候就可以再把它读出来使用。有些时候像银行卡号这些字段是不希望在网络上传输的,transient的作用就是把这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化,意思是transient修饰的age字段,他的生命周期仅仅在内存中,不会被写到磁盘中

被transient关键字修饰过得变量真的不能被序列化嘛?

是的

静态变量能被序列化吗?被transient关键字修饰之后呢?

静态变量是不会被序列化的,即使没有transient关键字修饰,因为静态成员变量实际上是属于类,而不是对象。

静态变量在全局区,本来流里面就没有写入静态变量,我打印静态变量当然会去全局区查找,而我们的序列化是写到磁盘上的,所以JVM查找这个静态变量的值,是从全局区查找的,而不是磁盘上。上面在改变static修饰的变量是在序列化后,但打印反序列化的对象的被static修饰的变量也同样改变了;这是因为在改变static修饰的变量时,是被写到了全局区,其实就是方法区,只不过被所有的线程共享的一块空间。
因此:
静态变量不管是不是transient关键字修饰,都不会被序列化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值