zoukankan      html  css  js  c++  java
  • 浅谈transient关键字

    1,用途
      当一个对象实现了Serilizable接口,这个对象就可以被序列化。而有时候我们可能要求:当对象被序列化时(写入字节序列到目标文件)时,有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
      所以,transient的用途在于:阻止实例中那些用此关键字声明的变量持久化。

    2,使用方法
    序列化的时候,将不需要序列化的属性前添加关键字transient即可。
    示例:

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    class UserInfo implements Serializable {  
        private static final long serialVersionUID = 996890129747019948L;  
        private String name;  
        private transient String psw;  
    
        public UserInfo(String name, String psw) {  
            this.name = name;  
            this.psw = psw;  
        }  
    
        public String toString() {  
            return "name=" + name + ", psw=" + psw;  
        }  
    }  
    public class TestTransient {
        public static void main(String[] args) {  
            UserInfo userInfo = new UserInfo("张三", "123456");  
            System.out.println(userInfo);  
            try {  
                // 序列化,被设置为transient的属性没有被序列化  
                ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("UserInfo.txt"));  
                o.writeObject(userInfo);  
                o.close();  
            } catch (Exception e) {  
                // TODO: handle exception  
                e.printStackTrace();  
            }  
            try {  
                // 重新读取内容  
                ObjectInputStream in = new ObjectInputStream(new FileInputStream("UserInfo.txt"));  
                UserInfo readUserInfo = (UserInfo) in.readObject();  
                //读取后psw的内容为null  
                System.out.println(readUserInfo.toString());  
            } catch (Exception e) {  
                // TODO: handle exception  
                e.printStackTrace();  
            }  
        }  
    }

    运行结果:

    1 name=张三, psw=123456
    2 name=张三, psw=null

    密码字段为null,说明被标记为transient的属性在对象被序列化的时候不会被保存

    使用小结:
      1,一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
      2,transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
      3,被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
      对于第三点,加上static之后,依然能把姓名输出。这是因为:反序列化后类中static型变量name的值为当前JVM中对应static变量的值,这个值是JVM中的不是反序列化得出的。下例可说明,其值时JVM中得到的而不是反序列化得到的:

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    class UserInfo implements Serializable {  
        private static final long serialVersionUID = 996890129747019948L;  
        private static String name;  
        private transient String psw;  
    
        public UserInfo(String name, String psw) {  
            this.name = name;  
            this.psw = psw;  
        }  
    
        public static String getName() {
            return name;
        }
    
        public static void setName(String name) {
            UserInfo.name = name;
        }
    
        public String getPsw() {
            return psw;
        }
    
        public void setPsw(String psw) {
            this.psw = psw;
        }
    
        public String toString() {  
            return "name=" + name + ", psw=" + psw;  
        }  
    }  
    public class TestTransient {
        public static void main(String[] args) {  
            UserInfo userInfo = new UserInfo("张三", "123456"); 
            System.out.println(userInfo);  
            try {  
                // 序列化,被设置为transient的属性没有被序列化  
                ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("UserInfo.txt"));  
                o.writeObject(userInfo);  
                o.close();  
            } catch (Exception e) {  
                // TODO: handle exception  
                e.printStackTrace();  
            }  
            try {  
                //在反序列化之前改变name的值
                userInfo.setName("hello");
                // 重新读取内容  
                ObjectInputStream in = new ObjectInputStream(new FileInputStream("UserInfo.txt"));  
                UserInfo readUserInfo = (UserInfo) in.readObject();  
                //读取后psw的内容为null  
                System.out.println(readUserInfo.toString());  
            } catch (Exception e) {  
                // TODO: handle exception  
                e.printStackTrace();  
            }  
        }  
    }

    运行结果:

    1 name=张三, psw=123456
    2 name=hello, psw=null

    这说明反序列化后类中static型变量name的值为当前JVM中对应static变量的值,为修改后hello,而不是序列化时的值“张三”

  • 相关阅读:
    linux全方位掌握一个命令--思路比方法更重要
    grep命令详解
    linux中的通配符与正则表达式
    sed命令使用详解归纳
    linux下命令行操作快捷键及技巧
    (原创)发布一个C++版本的ORM库SmartDB(一)
    (原创)C++11改进我们的程序之简化我们的程序(八)
    (原创)C++11改进我们的程序之简化我们的程序(七)
    (原创)C++11改进我们的程序之简化我们的程序(六)
    (原创)C++11改进我们的程序之简化我们的程序(五)
  • 原文地址:https://www.cnblogs.com/liuqing576598117/p/9843817.html
Copyright © 2011-2022 走看看