在Java中如何使用transient
2019独角兽企业重金招聘Python工程师标准>>>
Java语言的transient不像class、synchronized和其他熟悉的关键字那样众所周知,因而它会出现在一些面试题中。这篇文章我将为大家讲解transient。
transient的用途
Q:transient关键字能实现什么?
A:当对象被序列化时(写入字节序列到目标文件)时,transient阻止实例中那些用此关键字声明的变量持久化;当对象被反序列化时(从源文件读取字节序列进行重构),这样的实例变量值不会被持久化和恢复。例如,当反序列化对象——数据流(例如,文件)可能不存在时,原因是你的对象中存在类型为java.io.InputStream的变量,序列化时这些变量引用的输入流无法被打开。
transient使用介绍
Q:如何使用transient?
A:包含实例变量声明中的transient修饰符。片段1提供了小的演示。
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class ClassLib implements Serializable {
private transient InputStream is;
private int majorVer;
private int minorVer;
ClassLib(InputStream is) throws IOException {
System.out.println( "ClassLib(InputStream) called" );
this .is = is;
DataInputStream dis;
if (is instanceof DataInputStream)
dis = (DataInputStream) is;
else
dis = new DataInputStream(is);
if (dis.readInt() != 0xcafebabe )
throw new IOException( "not a .class file" );
minorVer = dis.readShort();
majorVer = dis.readShort();
}
int getMajorVer() {
return majorVer;
}
int getMinorVer() {
return minorVer;
}
void showIS() {
System.out.println(is);
}
}
public class TransDemo {
public static void main(String[] args) throws IOException {
if (args.length != 1 ) {
System.err.println( "usage: java TransDemo classfile" );
return ;
}
ClassLib cl = new ClassLib( new FileInputStream(args[ 0 ]));
System.out.printf( "Minor version number: %d%n" , cl.getMinorVer());
System.out.printf( "Major version number: %d%n" , cl.getMajorVer());
cl.showIS();
try (FileOutputStream fos = new FileOutputStream( "x.ser" );
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(cl);
}
cl = null ;
try (FileInputStream fis = new FileInputStream( "x.ser" );
ObjectInputStream ois = new ObjectInputStream(fis)) {
System.out.println();
cl = (ClassLib) ois.readObject();
System.out.printf( "Minor version number: %d%n" , cl.getMinorVer());
System.out.printf( "Major version number: %d%n" , cl.getMajorVer());
cl.showIS();
} catch (ClassNotFoundException cnfe) {
System.err.println(cnfe.getMessage());
}
}
}
|
片段1:序列化和反序列化ClassLib对象
片段1中声明ClassLib和TransDemo类。ClassLib是一个读取Java类文件的库,并且实现了 java.io.Serializable接口,从而这些实例能被序列化和反序列化。TransDemo是一个用来序列化和反序列化ClassLib实例 的应用类。
ClassLib声明它的实例变量为transient,原因是它可以毫无意义的序列化一个输入流(像上面讲述的那样)。事实上,如果此变量不是 transient的话,当反序列化x.ser的内容时,则会抛出java.io.NotSerializableException,原因是 InputStream没有实现Serializable接口。
编译片段1:javac TransDemo.java;带一个参数TransDemo.class运行应用:java TransDemo TransDemo.class。你或许会看到类似下面的输出:
1
2
3
4
5
6
7
8
|
ClassLib(InputStream) called
Minor version number: 0
Major version number: 51
java.io.FileInputStream@79f1e0e0
Minor version number: 0
Major version number: 51
null
|
以上输出表明:当对象被重构时,没有构造方法调用。此外,is假定默认为null,相比较,当ClassLib对象序列化时,majorVer和minorVer是有值的。
类中的成员变量和transient
Q:类中的成员变量中可以使用transient吗?
A:问题答案请看片段2
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
|
public class TransDemo {
public static void main(String[] args) throws IOException {
Foo foo = new Foo();
System.out.printf( "w: %d%n" , Foo.w);
System.out.printf( "x: %d%n" , Foo.x);
System.out.printf( "y: %d%n" , foo.y);
System.out.printf( "z: %d%n" , foo.z);
try (FileOutputStream fos = new FileOutputStream( "x.ser" );
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(foo);
}
foo = null ;
try (FileInputStream fis = new FileInputStream( "x.ser" );
ObjectInputStream ois = new ObjectInputStream(fis)) {
System.out.println();
foo = (Foo) ois.readObject();
System.out.printf( "w: %d%n" , Foo.w);
System.out.printf( "x: %d%n" , Foo.x);
System.out.printf( "y: %d%n" , foo.y);
System.out.printf( "z: %d%n" , foo.z);
} catch (ClassNotFoundException cnfe) {
System.err.println(cnfe.getMessage());
}
}
}
|
片段2:序列化和反序列化Foo对象
片段2有点类似片段1。但不同的是,序列化和反序列化的是Foo对象,而不是ClassLib。此外,Foo包含一对变量,w和x,以及实例变量y和z。
编译片段2(javac TransDemo.java)并运行应用(java TransDemo)。你可以看到如下输出:
1
2
3
4
5
6
7
8
9
|
w: 1
x: 2
y: 3
z: 4
w: 1
x: 2
y: 3
z: 0
|
这个输出告诉我们,实例变量y是被序列化的,z却没有,它被标记transient。但是,当Foo被序列化时,它并没有告诉我们,是否变量w和x被序列化和反序列化,是否只是以普通类初始化方式初始。对于答案,我们需要查看x.ser的内容。
下面显示x.ser十六进制:
1
2
|
00000000 AC ED 00 05 73 72 00 03 46 6F 6F FC 7A 5D 82 1D ....sr..Foo.z]..
00000010 D2 9D 3F 02 00 01 49 00 01 79 78 70 00 00 00 03 ..?...I..yxp....
|
由于JavaWorld中的“The Java serialization algorithm revealed”这篇文章,我们发现输出的含义:
AC ED 序列化协议标识
00 05 流版本号
73 表示这是一个新对象
72 表示这是一个新的类
00 03 表示类名长度(3)
46 6F 6F 表示类名(Foo)
FC 7A 5D 82 1D D2 9D 3F 表示类的串行版本标识符
02 表示该对象支持序列化
00 01 表示这个类的变量数量(1)
49 变量类型代码 (0×49, 或I, 表示int)
00 01 表示变量名长度(1)
79 变量名称(y)
78 表示该对象可选的数据块末端
70 表示我们已经到达类层次结构的顶部
00 00 00 03 表示y的值(3)
显而易见,只有实例变量y被序列化。因为z是transient,所以不能序列化。此外,即使它们标记transien,w和x不能被序列化,原因是它们类变量不能序列化。
转载于:https://my.oschina.net/u/2288146/blog/530814
在Java中如何使用transient相关推荐
- java transient_【转】Java中的关键字 transient
阅读目录 先解释下Java中的对象序列化 在讨论transient之前,有必要先搞清楚Java中序列化的含义: Java中对象的序列化指的是将对象转换成以字节序列的形式来表示,这些字节序列包含了对象的 ...
- java中的关键字transient说明
这个关键字的作用其实我在写java的序列化机制中曾经写过,不过那时候只是简单地认识,只要其简单的用法,没有深入的去分析.这篇文章就是去深入分析一下transient关键字. 先给出这篇文章的大致脉络 ...
- [转载] JAVA中transient 关键字
参考链接: Java中的transient关键字 今天学习到对象流,序列化反序列化的时候,老师用了一个transient关键字来防止某个属性被序列化,脑子一头懵逼,于是在网上看到了找了别人的博客,也不 ...
- java工作笔记020---Java中的关键字 transient
技术交流QQ群[JAVA,C,.NET,BigData,AI]:170933152 先解释下Java中的对象序列化 在讨论transient之前,有必要先搞清楚Java中序列化的含义: Java中对象 ...
- Java中对象的串行化(Serialization)和transient关键字
Java中对象的串行化(Serialization)和transient关键字 前言: 该篇文章参考自网上资料,但是部分内容经过笔者更改,因此算作原创吧,原文地址: http://www.golden ...
- java中transient关键字使用学习
导师让我学习序列化和反序列化的时候才意识到自己的对java中的transient关键字不熟.看了很多介绍和学习笔记之后,对transient关键字的使用做一下总结: 如果一个对象只要实现了Serili ...
- java中的transient关键字详解
前言 说实话学了一段时间java的朋友对于transient这个关键字依旧很陌生基本没怎么用过,但是transient关键字在java中却起到了不可或缺的地位!如果要说讲到,我觉得最可能出现的地方是I ...
- Java中的transient关键字
前言 说实话学了一段时间java的朋友对于transient这个关键字依旧很陌生基本没怎么用过,但是transient关键字在java中却起到了不可或缺的地位!如果要说讲到,我觉得最可能出现的地方是I ...
- Java中transient关键字的详细总结
目录 一.概要介绍 1. 序列化 2. 为什么要用transient关键字? 3. transient的作用 二.transient使用总结 三.使用场景 一.概要介绍 本文要介绍的是Java中的tr ...
最新文章
- 漫画算法:如何判断链表有环?
- ISA2004发布应用程序服务器
- 最小代价(区间dp)(ybtoj)
- java char类型空值_展望Java的未来:空值类型
- MySQL索引优化分析
- java switch中标签重复_java程序 怎样把id相同的记录挑出来,分别存到不同的文件中,除了switch case,数据量很大,id种类很多。...
- 小心!!,使用缓存的陷阱
- 第二季-专题0-课程规划
- 微信配网airkiss
- MCE公司:Pfizer入局IDO1小分子抑制剂
- glsl中uniform,attribute和varying详解
- ISP Pipeline lens shading
- ovf导入虚拟服务器,云主机 导入 ovf
- 保姆级教程:群晖nas内网穿透之ipv6/ipv4 ddns+frp双管齐下!
- 北航计算机学院往年夏令营+考研面试题目汇总
- python计算银行余额_Python 小案例实战 —— 简易银行存取款查询系统
- es6 语法,在 IE 中不兼容的处理办法
- 【关于echarts使用所遇问题01】---- Unable to preventDefault inside passive event listener invocation
- (转) 值得关注的开源软件推荐
- java图形验证码识别-阿里云OCR(精准率50%)
热门文章
- Java 二次MD5 32位小写加密算法与php页面加密结果相同
- 企业管理软件的需求描述方法
- 理解 QEMU/KVM 和 Ceph(2):QEMU 的 RBD 块驱动(block driver)
- Eclipse里的Java EE视图在哪里?MyEclipse里的Java EE视图在哪里?MyEclipse里的MyEclipse Java Enterprise视图在哪里?(图文详解)...
- Oracle“死锁”模拟
- 解读《电力发展“十三五”规划》
- Java编译那些事儿【转】
- goaccess在定时任务中不执行的问题
- OSChina 周三乱弹 —— 程序员火灾逃生指南
- 教你打造优秀IT博文