Java中transient字段的作用及使用场景

Java中transient字段的作用及使用场景

技术背景

在Java编程里,序列化是一项关键技术,它能把对象状态转化为字节流,用于存储(如存入文件)或传输(如在网络上发送)。反序列化则是将字节流恢复成对象状态的过程。不过,并非所有对象的字段都需要被序列化,这时就需要transient关键字来发挥作用。

实现步骤

1. 理解序列化和transient关键字

在Java中,要让一个类的对象能够被序列化,该类必须实现Serializable接口。transient关键字用于标记那些不需要参与序列化过程的字段。

2. 标记transient字段

在类的定义中,使用transient关键字标记不需要序列化的字段。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class GalleryImage implements Serializable {
private Image image;
private transient Image thumbnailImage;

private void generateThumbnail() {
// Generate thumbnail.
}

private void readObject(ObjectInputStream inputStream)
throws IOException, ClassNotFoundException {
inputStream.defaultReadObject();
generateThumbnail();
}
}

3. 反序列化时恢复对象状态

在反序列化时,可能需要手动恢复对象的状态。可以通过重写readObject方法来实现。如上述示例,在反序列化时调用generateThumbnail方法生成缩略图。

核心代码

示例一:GalleryImage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class GalleryImage implements Serializable {
private Image image;
private transient Image thumbnailImage;

private void generateThumbnail() {
// Generate thumbnail.
}

private void readObject(ObjectInputStream inputStream)
throws IOException, ClassNotFoundException {
inputStream.defaultReadObject();
generateThumbnail();
}
}

示例二:NameStore

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package javabeat.samples;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class NameStore implements Serializable {
private String firstName;
private transient String middleName;
private String lastName;

public NameStore(String fName, String mName, String lName) {
this.firstName = fName;
this.middleName = mName;
this.lastName = lName;
}

public String toString() {
StringBuffer sb = new StringBuffer(40);
sb.append("First Name : ");
sb.append(this.firstName);
sb.append("Middle Name : ");
sb.append(this.middleName);
sb.append("Last Name : ");
sb.append(this.lastName);
return sb.toString();
}
}

public class TransientExample {
public static void main(String args[]) throws Exception {
NameStore nameStore = new NameStore("Steve", "Middle", "Jobs");
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("nameStore"));
// writing to object
o.writeObject(nameStore);
o.close();

// reading from object
ObjectInputStream in = new ObjectInputStream(new FileInputStream("nameStore"));
NameStore nameStore1 = (NameStore) in.readObject();
System.out.println(nameStore1);
}
}

最佳实践

  • 避免序列化不必要的字段:对于那些可以从其他字段推导出来的字段,或者在反序列化时可以重新计算的字段,应标记为transient,以减少序列化对象的存储空间。
  • 重写readObject方法:在反序列化时,如果需要恢复对象的状态,可以重写readObject方法,在其中进行必要的操作。

常见问题

1. transient字段在反序列化后的值是什么?

transient字段在反序列化后的值为其默认值,如引用类型为null,基本类型为对应基本类型的默认值。

2. 静态字段需要标记为transient吗?

静态字段不会被序列化,因为静态字段属于类,而不是对象。不过,如果出于设计考虑,也可以将其标记为transient

3. transient字段可以是局部变量吗?

不可以,transient关键字只能用于类的成员变量,不能用于局部变量。


Java中transient字段的作用及使用场景
https://119291.xyz/posts/java-transient-fields-usage/
作者
ww
发布于
2025年5月28日
许可协议