序列化和反序列化 && java中的 关键字transient


之前在研究java中ArrayList源码。在ArrayList的域中有 transient Object[] elementData (Object类型的数组elementData被transient修饰)。此处黑人问号?关键字transient是啥?

1.在此之前我们需要了解一下什么是序列化和反序列化

把对象转换为字节序列的过程称为对象的序列化
把字节序列恢复为对象的过程称为对象的反序列化

下面举一个简单的例子帮助大家理解:
比如在一个学生类的ArrayList中,其中有一个 name = ‘Bob’,现在我们把name ‘Bob’改成’Bill’。但是一旦程序结束,变量所占用的内存就被操作系统全部回收。如果没有把修改后的’Bill’存储到磁盘上,下次重新运行程序,变量又被初始化为’Bob’。不过好在ArrayList是可序列化的。

2.关键字transient(临时的)(用来表示一个域不是该对象序行化的一部分)

1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。

2)一个静态变量不管是否被transient修饰,均不能被序列化。

3)transient关键字修饰范围,只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。

举例


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("Alexia");
        user.setPasswd("123456");
 
        System.out.println("read before Serializable: ");
        System.out.println("username: " + user.getUsername());
        System.err.println("password: " + user.getPasswd());
 
        try {
            ObjectOutputStream os = new ObjectOutputStream(
                    new FileOutputStream("D:/user.txt"));
            os.writeObject(user); // 将User对象写进文件
            os.flush();
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            // 在反序列化之前改变username的值
            User.username = "jmwang";
 
            ObjectInputStream is = new ObjectInputStream(new FileInputStream(
                    "D:/user.txt"));
            user = (User) is.readObject(); // 从流中读取User的数据
            is.close();
 
            System.out.println("\nread after Serializable: ");
            System.out.println("username: " + user.getUsername());
            System.err.println("password: " + user.getPasswd());
 
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
 
class User implements Serializable {
    private static final long serialVersionUID = 8294180014912103005L;  
 
    public static String username;
    private transient String passwd;
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public String getPasswd() {
        return passwd;
    }
 
    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }
 
}

这时我们发现结果如图所示:
在这里插入图片描述
密码字段为null,说明反序列化时根本没有从文件中获取到信息。密码从开始就没有参与序列化。

猜你喜欢

转载自blog.csdn.net/qq_43507104/article/details/89609118