`

Java关键字——transient

阅读更多
眼看就要2012了,这一年给自己树立的研究课题基本上因为工作的转型,最终都没能实现。开发经验开始消减,更没能赶上新技术。终于,我要恢复开发经验! 找回曾经的我!

最近被问到很多Java基础性的问题,突然发现自己长时间沉迷于框架整合的乐趣中,有关于底层这方面原来不曾深度研究,有必要恶补下了。
“transient”——“瞬态”,先不说这个翻译是否恰当,这个变量关键字一直不曾使用,简单的说就是被瞬态定义的变量不可序列号。或者这么给他换个名字——“不可序列化状态”?
打个比方,如果一个用户有一些敏感信息(譬如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输。这些信息对应的变量就可以被定义为transient类型。换句话说,这个字段的生命周期仅存于调用者的内存中。
定义People
public class People implements Serializable {
	private static final long serialVersionUID = 8294180014912103005L;

	/**
	 * 用户名
	 */
	private String username;
	/**
	 * 密码
	 */
	private transient String password;
}


密码字段为transient,这时候如果对该对象进行序列化,这个密码字段是不会被保存的。
为了代码简洁,未将流操作至于try-catch中,仅为演示,勿仿!
public static void main(String[] args) throws Exception {

		People p = new People();
		p.setUsername("snowolf");
		p.setPassword("123456");

		System.err.println("------操作前------");
		System.err.println("username: " + p.getUsername());
		System.err.println("password: " + p.getPassword());

		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
				"people.txt"));
		oos.writeObject(p);
		oos.flush();
		oos.close();

		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
				"people.txt"));
		p = (People) ois.readObject();

		ois.close();

		System.err.println("------操作后------");
		System.err.println("username: " + p.getUsername());
		System.err.println("password: " + p.getPassword());

	}

执行操作:
引用
------操作前------
username: snowolf
password: 123456
------操作后------
username: snowolf
password: null

密码字段为null,反序列化时根本没有从文件中获取到信息。
这个变量类型,理解起来都不费事,但就是适用场景,我一直纠结。
暂时整理如下,欢迎拍砖补充!
适用场景:
1.不打算序列化某字段的值,节省空间
2.传递序列化流的时候,不传递该值等


如上信息似乎跟JNI有关,欢迎拍砖!

11
7
分享到:
评论
10 楼 ifox 2013-07-23  
phrmgb 写道
学习了,这些东东有时感觉很偏的,但是特殊的业务用到这些知识

我看java许多源码都用到了呐。
9 楼 wushipan_easy 2011-12-30  
收藏一下,以后慢慢看
8 楼 PV_love 2011-12-30  
楼主写了
“为了代码简洁,未将流操作至于try-catch中,仅为演示,勿仿!”我没看到。
“比如说用transient定义一个int变量,用做计数,序列化/反序列化后必须重新核算。”
int变量不想写入流中,又得保证序列化前后一致,那之后就得再算一遍int变量的值,要不然有什么好办法么?

7 楼 snowolf 2011-12-30  
PV_love 写道
1.楼主的代码中,有关文件的操作应该放入try catch 中..
2.transient标识变量的作用是序列化的时候跳过该变量,主要应用的场景应该对象型的变量。
例如

class Hair{
private hairLength;
public Hair(int length){hairLength=length}
}

class body implements Serializable{
private Hair hair;
....
}

hair是body的成员变量,要保存body的时候需要保存hair,这就需要hair是序列化的,但是由于某些原因hair不是序列化的,那么就需要将hair标识成transient,序列化的时候跳过hair,但是可以将表示hair的状态,例如本例中的hairLength保存在流之中,然后在反序列化的时候,将hair变量通过hairLength重新生成,虽然没有保存hair本身,但是保存了表示hair的变量hairLength

我还没试过楼主的那种用法,用transient标识string型的变量,不知道这样可以可以。
如果可以,像这样的保存密码,反序列化的时候如何获得原来的密码呢?
安全方面的知识我不是很了解,我猜可能是将密码md5加密之后在再进行序列化,虽然理论上任何密码都是可以被破解的,但是网络上传输的密码都是这种方式吧?


为了代码简洁,我抛开了try-catch.
网络密文交互要比这个复杂,有安全强度要求。如想了解可以参考我的加密解密系列帖子。
别我用一个password字段,把大家引导沟里去了。
比如说用transient定义一个int变量,用做计数,序列化/反序列化后必须重新核算。这个意义就比较明显。对于这个瞬时变量不需要存储,只需要在内存中重新核算。期待继续拍砖!!拍出个金豆子!
6 楼 PV_love 2011-12-30  
1.楼主的代码中,有关文件的操作应该放入try catch 中..
2.transient标识变量的作用是序列化的时候跳过该变量,主要应用的场景应该对象型的变量。
例如

class Hair{
private hairLength;
public Hair(int length){hairLength=length}
}

class body implements Serializable{
private Hair hair;
....
}

hair是body的成员变量,要保存body的时候需要保存hair,这就需要hair是序列化的,但是由于某些原因hair不是序列化的,那么就需要将hair标识成transient,序列化的时候跳过hair,但是可以将表示hair的状态,例如本例中的hairLength保存在流之中,然后在反序列化的时候,将hair变量通过hairLength重新生成,虽然没有保存hair本身,但是保存了表示hair的变量hairLength

我还没试过楼主的那种用法,用transient标识string型的变量,不知道这样可以可以。
如果可以,像这样的保存密码,反序列化的时候如何获得原来的密码呢?
安全方面的知识我不是很了解,我猜可能是将密码md5加密之后在再进行序列化,虽然理论上任何密码都是可以被破解的,但是网络上传输的密码都是这种方式吧?

5 楼 沙舟狼客 2011-12-30  
transient,这个关键字用的不多
4 楼 phrmgb 2011-12-29  
学习了,这些东东有时感觉很偏的,但是特殊的业务用到这些知识
3 楼 snowolf 2011-12-29  
snowolf 写道
jyjava 写道
lz,你顺便讲讲volatile呀

这个“挥发态”跟序列化没关系,跟线程安全有关。我需要研究下如何模拟测试。。。

据说它比synchronized效率更高!
2 楼 snowolf 2011-12-29  
jyjava 写道
lz,你顺便讲讲volatile呀

这个“挥发态”跟序列化没关系,跟线程安全有关。我需要研究下如何模拟测试。。。
1 楼 jyjava 2011-12-29  
lz,你顺便讲讲volatile呀

相关推荐

    Java入门——Java修饰词总结

    Java作为一门广泛使用的编程语言,拥有丰富的语法结构和关键字,其中修饰词(modifiers)是Java语言中的重要组成部分,用于限定类、方法、字段等的访问级别、生命周期以及特性。以下是对Java中11个修饰词的详细介绍...

    2.java学习第二章——标识符与关键字.pdf

    Java关键字是由Java语言定义的一系列具有特殊含义的单词,它们不能作为普通的标识符来使用。关键字在Java程序设计中起着至关重要的作用,用于定义各种语言结构和控制流。 #### 关键字分类: 1. **用于定义数据类型...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    在 java 语言中,Java 程序的基本单位是类,也就是说:一个 Java 程序是由多个类组成 的。定义一个类与定义一个数据类型是有区别的。在程序设计语言中,把定义数据类型的能 力作为一种很重要的能力来对待。在面向...

    ArrayList源码解析(数据结构及底层实现)(csdn)————程序.pdf

    ArrayList 是 Java 中常用的动态数组,它是 List 接口的一个实现,允许我们在列表的任何位置插入和删除元素。ArrayList 的核心数据结构是一个可变大小的数组,即 `elementData`。在深入源码解析之前,先了解一下 ...

    java复习资源

    28. **序列化关键字**:在Java的序列化机制中,如果有些变量不需要被序列化,可以使用关键字`transient`来标记。 #### 二十九、Swing组件绘图 29. **Swing组件绘图**:如果要在`Swing`组件`JPanel`表面上画图,...

    JAVA集合介绍

    ### JAVA集合介绍——深入理解ArrayList #### 一、ArrayList概述 `ArrayList` 是 `java.util.List` 接口的一种实现,其本质是一个动态数组。它能够根据需要动态地调整其大小,以适应列表中元素数量的变化。`...

    java基础语法讲解上集,适合初级人员入门学习

    - 不能是Java关键字。 - 区分大小写。 - **命名约定**: - 包名:所有字母都小写。 - 类名/接口名:每个单词首字母大写。 - 变量名/方法名:首单词首字母小写,后续单词首字母大写。 - 常量名:所有字母大写,...

    一个Java序列化反序列化库,用于将Java对象转换为JSON和返回JSON.zip

    2. 创建Java对象:定义要序列化的类,并确保类及其属性不包含 transient 或 static 关键字,因为这些字段不会被序列化。 3. 序列化:使用Gson实例将Java对象转换为JSON字符串。 ```java Gson gson = new Gson(); ...

    计算机Java核心编程笔记

    2. **数据类型**:Java有两类数据类型——基本数据类型和引用数据类型。基本数据类型包括8种:`boolean`、`byte`、`short`、`int`、`long`、`float`、`double`和`char`。引用数据类型包括类、接口和数组,例如`...

    计算机java核心编程

    2. **数据类型**:Java有两类数据类型——基本数据类型和引用数据类型。基本数据类型包括布尔型(`boolean`)、整型(`byte`、`short`、`int`、`long`)、浮点型(`float`、`double`)、字符型(`char`)和布尔型(`...

    JAVA教程 第二讲 Java语言基础知识

    - **保留字(关键字)**:Java有一系列具有特殊意义和用途的单词,不能作为一般标识符使用。这些词包括但不限于`abstract`, `break`, `byte`, `boolean`, `catch`, `case`, `class`, `char`, `continue`, `default`,...

    计算机Java编程笔记

    2. **数据类型**:Java提供了两种类型的数据类型——**基本数据类型**和**引用数据类型**。基本数据类型包括8种:`boolean`、`byte`、`short`、`int`、`long`、`float`、`double`和`char`。引用数据类型主要包括类、...

    基于Java的存储与读取对象.zip

    谨慎地设计你的序列化策略,并考虑使用`transient`关键字标记那些不希望被序列化的字段。 - **效率**:序列化和反序列化可能需要一定的计算资源,对于大数据量的对象,要考虑性能影响。 - **序列化ID**:如果类没有...

    面向对象理论——太基础了以至于面试出错

    类是Java中的基本构建块,它通过`class`关键字定义。类可以包含属性(变量)和方法(函数)。类的一般语法结构如下: ```java [修饰符] class 类名 [extends 父类] [implements 接口名] { 类成员变量声明; 类...

    经典中兴——软件笔试

    【标题】"经典中兴——软件笔试"涵盖了多个IT领域的知识点,主要集中在数据结构与算法、软件工程以及Java语言及其他编程基础知识。以下是这些知识点的详细解释: **数据结构与算法** 1. 这道题目涉及到了时间复杂度...

    java终极测试题(中兴.华维)

    Java集合框架——List - **List接口**:`List`是Java集合框架的一部分,提供了有序的元素集合,并允许重复元素。 - **实现类**:`ArrayList`是一种动态数组实现的`List`,适合频繁的读取操作。 - **示例代码**:...

    Java 的对象永续之道

    - **transient关键字**:用来标记不希望被序列化的成员变量。这些变量不会被包含在序列化的输出中。 ##### 4.2 反射的应用 序列化过程中,Java利用反射机制来获取对象的所有属性和方法,从而能够正确地序列化对象...

    java语言实验3指导面向对象程序设计继承、封装、多态.docx

    本次实验的主要目的是深入理解并实践Java中的面向对象编程(OOP)核心概念——继承、封装与多态。通过实际操作,学员将能够更加熟练地运用这些特性来构建灵活且可扩展的软件系统。 #### 面向对象编程基础 - **类**:...

    java语言笔记包括基本数据类型、变量类型、修饰符、运算符等

    ### Java语言笔记——基本数据类型、变量类型、修饰符、运算符详解 #### 一、Java基本数据类型 Java提供了两种基本的数据类型:内置数据类型和引用数据类型。内置数据类型可以直接存储数值,而引用数据类型则存储...

Global site tag (gtag.js) - Google Analytics