transient关键字的一些注意点

一. transient关键字的概述:

在平常开发中,如果某个类实现了Serializable接口,则这个类就可以被序列化,然而如果某些属性,我们不想序列化,则我们可以使用transient关键字修饰,在序列化对象时,这些被transient修饰的属性就可以不被序列化。

二. transient关键字注意点:

1. transient关键字只能修饰属性,不能修饰方法跟类。如果该属性是我们自定义的类对象,则这个自定义的类需要实现Serializable接口。

2. static修饰的属性无论有没有transient修饰,均不能被序列化。(其实在平时开发中,你会发现序列化后在发序列化,static修饰的属性还是有值的,但是,这个值不是序列化得来的,而是JVM中对应的static变量的值)测试:

①有一个实体类User

class User implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 4116444461933762681L;
    private static String userName;
    private transient String passwrod;
    
    public User() {
        super();
    }

    public User(String userName, String passwrod) {
        super();
        this.userName = userName;
        this.passwrod = passwrod;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPasswrod() {
        return passwrod;
    }

    public void setPasswrod(String passwrod) {
        this.passwrod = passwrod;
    }
}

②序列化的代码:

public static void testObjectOutputStream(User user) {
        try(ObjectOutputStream outputStream =
                new ObjectOutputStream(new FileOutputStream("xy.txt"))
            ) {
            System.out.println("序列化之前:");
            System.out.println("username: " + user.getUserName());
            System.out.println("password: " + user.getPasswrod());
            outputStream.writeObject(user);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

③反序列化的代码:

public static void testObjectInputStream() {
        try(ObjectInputStream inputStream =
                new ObjectInputStream(new FileInputStream("xy.txt"))) {
            User user = new User();
            user.setUserName("xxxx");
            user = (User) inputStream.readObject();
            System.out.println("反序列化后: ");
            System.out.println("username: " + user.getUserName());
            System.out.println("password: " + user.getPasswrod());
        } catch(IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

④测试:

public static void main(String[] args) {
        testObjectOutputStream(new User("xuy", "1229"));
        testObjectInputStream();
    }

运行结果:

我们发现,static修饰的username序列化之前是xuy,我们在反序列化之前我们对username的值进行了重新赋值,然后反序列化得到的值却为xxxx,这是因为静态变量username是JVM中对应的static变量,而不是序列化后得到的值。

三. transient修饰的变量是否真的不能被序列化?

我们知道,序列化有两种方式,一种是实现Serializable接口,另一种是实现Externalizable接口,两者的区别是:如果实现的是Serializable接口,则会自动的进行序列化。如果实现的是Externalizable接口,我们需要手动的进行序列化。

public class TransientDemo implements Externalizable {
    
    private transient String str = "today is 2018-02-05, and this is about keyword transient";

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(str);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        in.readObject();
    }
    
    public static void main(String[] args) {
        testObjectOutputStream();
        testObjectInputStream();
    }
    
    public static void testObjectOutputStream() {
        try(ObjectOutputStream ous =
                new ObjectOutputStream(new FileOutputStream("xy.txt"))) {
            
            ous.writeObject(new TransientDemo());
            ous.flush();
            
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void testObjectInputStream() {
        try(ObjectInputStream oin =
                new ObjectInputStream(new FileInputStream("xy.txt"))) {
            
            TransientDemo readObject = (TransientDemo) oin.readObject();
            System.out.println(readObject.str);
            
        } catch(IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
}

其中writeExternal()方法调用如下:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值