java中的transient关键字
1、介绍
在本文中,我们先讲解一下transient关键字,之后我们会通过几个案例来看下具体的用法。
2、transient的用法
在理解transient之前,我们要先弄清楚java中的序列化。序列化指的是把一个java对象转化成一个字节流。反序列化则相反,它是把一个字节流转化为一个java对象。当我们把某个变量标记为transient时,之后该变量就不会被序列化了。因此,序列化进程transient变量的原始值会被忽略,并且之会保存其数据类型所对应的默认值。
在以下这些场景中,transient关键字是非常有用的:
. 我们可以使用它处理衍生字段
. 我们可以用它来处理那些和对象状态无关的字段
. 我们可以用它来处理那些不能序列化的引用字段
3、案例
我们通过一个例子来看。我们先创建一个Book类,然后我们对这个Book类的对象执行序列化。
/**
* @Author: chihaojie
* @Date: 2021/2/24 10:45
* @Version 1.0
* @Note
*/
public class Book implements Serializable {
private static final long serialVersionUID = -2936687026040726549L;
private String bookName;
private transient String description;
private transient int copies;
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getCopies() {
return copies;
}
public void setCopies(int copies) {
this.copies = copies;
}
}
这里,我们把description和copies字段标记为transient。创建完这个类之后,我们再创建一个该类的对象。
Book book = new Book();
book.setBookName("Java Reference");
book.setDescription("will not be saved");
book.setCopies(25);
现在,我们把这个对象序列化进一个文件中:
public static void serialize(Book book) throws Exception {
FileOutputStream file = new FileOutputStream(fileName);
ObjectOutputStream out = new ObjectOutputStream(file);
out.writeObject(book);
out.close();
file.close();
}
接着我们再从文件中反序列化此对象:
public static Book deserialize() throws Exception {
FileInputStream file = new FileInputStream(fileName);
ObjectInputStream in = new ObjectInputStream(file);
Book book = (Book) in.readObject();
in.close();
file.close();
return book;
}
完整的程序示例为:
public class TransientMain {
public static void main(String[] args)throws Exception {
Book book = new Book();
book.setBookName("Java Reference");
book.setDescription("will not be saved");
book.setCopies(25);
serialize(book);
Book deserializeBook = deserialize();
System.out.println(deserializeBook.getBookName());
System.out.println(deserializeBook.getDescription());
System.out.println(deserializeBook.getCopies());
}
public static void serialize(Book book) throws Exception{
FileOutputStream file = new FileOutputStream("book.txt");
ObjectOutputStream out = new ObjectOutputStream(file);
out.writeObject(book);
out.close();
file.close();
}
public static Book deserialize() throws Exception{
FileInputStream file = new FileInputStream("book.txt");
ObjectInputStream in = new ObjectInputStream(file);
Book book = (Book) in.readObject();
in.close();
file.close();
return book;
}
}
控制台的输出如下:
我们可以看到,bookName字段被序列化了,而copies字段的值为0,description字段的值为null-这都是他们各自所属数据类型的默认值-而不是它们原本的字段值。
4、transient和final组合使用
我们再来看一个特殊的场景,我们把transient和final组合在一起使用。要做到这点,首先,我们在Book类中新增一个final transient字段,接着,我们再创建一个空的Book对象。
public class Book implements Serializable {
private static final long serialVersionUID = -2936687026040726549L;
private String bookName;
private transient String description;
private transient int copies;
private final transient String bookCategory = "Fiction";
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getCopies() {
return copies;
}
public void setCopies(int copies) {
this.copies = copies;
}
public String getBookCategory() {
return bookCategory;
}
}
测试程序:
public class TransientMain {
public static void main(String[] args)throws Exception {
Book book = new Book();
book.setBookName("Java Reference");
book.setDescription("will not be saved");
book.setCopies(25);
serialize(book);
Book deserializeBook = deserialize();
System.out.println(deserializeBook.getBookName());
System.out.println(deserializeBook.getDescription());
System.out.println(deserializeBook.getCopies());
System.out.println(deserializeBook.getBookCategory());
}
public static void serialize(Book book) throws Exception{
FileOutputStream file = new FileOutputStream("book.txt");
ObjectOutputStream out = new ObjectOutputStream(file);
out.writeObject(book);
out.close();
file.close();
}
public static Book deserialize() throws Exception{
FileInputStream file = new FileInputStream("book.txt");
ObjectInputStream in = new ObjectInputStream(file);
Book book = (Book) in.readObject();
in.close();
file.close();
return book;
}
}
运行程序,观察控制台的输出情况:
5、总结
在本文中,我们介绍了transient关键字的用法,以及它在序列化和反序列化中的作用。同时,我们也看到了它和final组合使用时效果。