Java 中的 transient 关键字

transient:
adj. 转瞬即逝的,短暂的;暂住的,(工作)临时的
n. 暂住者,流动人口;(电流、电压、频率的)瞬变

transient 的作用和使用方法:

我们知道对象实现了 serilizable 就可以被序列化,我们不必关系具体序列化的过程,只要实现了这个接口,这个类的所有属性和方法都会自动的序列化
在实际的开发过程中,为了安全起见,通常我们并不希望所有的属性都被序列化在网络操作中传输,那么此时我们只需要在 不希望序列化的属性前,添加 transient 关键字即可。

1. 需要实现 serilizible 接口
2. 在不希望被序列化的属性前,添加 transient 关键字。

示例CODE

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 TransientDemo {
    
    public static void main(String[] args) {
        
        User user = new User();
        user.setUsername("wddong");
        user.setPassword("123456");
        
        System.out.println("read before Serializable: "+ user);
        
        try {
            ObjectOutputStream os = new ObjectOutputStream(
                    new FileOutputStream("E:/temp/user.txt"));
            os.writeObject(user); // 将User对象写进文件
            os.flush();
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            ObjectInputStream is = new ObjectInputStream(new FileInputStream(
                    "E:/temp/user.txt"));
            user = (User) is.readObject(); // 从流中读取User的数据
            is.close();
            
            System.out.println("\nread after Serializable: "+ user);
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

@Data
class User implements Serializable {
    private static final long serialVersionUID = 8294180014912103005L;  
    
    private String username;
    private transient String password;
}

程序输出:

read before Serializable: : User(username=wddong, password=12345)
read after Serializable: : User(username=wddong, password=null)

密码字段为null,可以看出反序列化没有从文件中获取到信息。

小结:

  1. 变量一旦被 transient 修饰,变量将不再会是持久化的一部分。
  2. transient 关键字只能够修饰变量,不能够用来修饰方法和类。
  3. transient 修饰的变量不能被持久化,而 static 修饰的变量不论有没有被 transient 修饰,都不能被序列化。

为什么被 static 修饰的变量不论是否被transient ,不能被序列化??

还是以上的示例,改造一下。(static 型变量为当前JVM中对应的static 变量的值)

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 TransientTest {
    
    public static void main(String[] args) {
        
        User user = new User();
        user.setUsername("wddong");
        user.setPasswd("123456");
        
        System.out.println("read before Serializable: "+user);
        
        try {
            ObjectOutputStream os = new ObjectOutputStream(
                    new FileOutputStream("E:/temp/user.txt"));
            os.writeObject(user); // 将User对象写进文件
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        } 
        try {
            // 在反序列化之前改变username的值
            User.username = "jmwang";
            ObjectInputStream is = new ObjectInputStream(new FileInputStream(
                    "E:/temp/user.txt"));
            user = (User) is.readObject(); // 从流中读取User的数据
            is.close();
            
            System.out.println("\nread after Serializable: " + user);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@Data
class User implements Serializable {
    private static final long serialVersionUID = 8294180014912103005L;  
    public static String username;
    private transient String passwd;
}

程序输出:

read before Serializable: : User(username=wddong, password=12345)
read after Serializable: : User(username=jmwang, password=null)

== 这说明反序列化后类中static型变量username的值为当前JVM中对应static变量的值,为修改后jmwang,而不是序列化时的值wddong。==

被 transient 修饰的变量是否一定不能被序列化??

不是,transient 和 serilizible 配合使用,被修饰的变量不能被序列化,serilizible 接口是自动序列化接口,继承了这个接口的类会被自动的序列化,除了 serilizible 接口,还有Externalizable 接口。若实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王叮咚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值