翻译自http:
//
www.devx.com/tips/Tip/13726。
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想
用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
注意static变量也是可以串行化的
首先,让我们看一些Java serialization的代码:
class LoggingInfo implements java.io.Serializable {
private Date loggingDate = new Date();
private String uid;
private transient String pwd;
LoggingInfo(String user, String password) {
uid = user;
pwd = password;
}
public String toString() {
String password = null;
if (pwd == null) {
password = "NOT SET";
} else {
password = pwd;
}
return "logon info: \n " + "user: " + uid + "\n logging date : " + loggingDate.toString()
+ "\n password: " + password;
}
}
现在我们创建一个这个类的实例,并且串行化(serialize)它 ,然后将这个串行化对象写如磁盘。
public class TestTransient {
@SuppressWarnings("serial")
public static void main(String[] args) {
LoggingInfo logInfo = new LoggingInfo("MIKE", "MECHANICS");
System.out.println(logInfo.toString());
ObjectOutputStream o;
try {
o = new ObjectOutputStream(new FileOutputStream("d:logInfo.out"));
o.writeObject(logInfo);
o.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("d:logInfo.out"));
LoggingInfo logInfo2 = (LoggingInfo) in.readObject();
System.out.println(logInfo2.toString());
} catch (Exception e) {// deal with exception
e.printStackTrace();
}
}
}
如果我们运行这段代码,我们会注意到从磁盘中读回(read——back (de
-
serializing))的对象打印password为
"
NOT SET
"
。这是当我们定义pwd域为transient时,所期望的正确结果。
logon info:
user: MIKE
logging date : Thu Apr 28 17:28:12 CST 2011
password: MECHANICS
logon info:
user: MIKE
logging date : Thu Apr 28 17:28:12 CST 2011
password: NOT SET
现在,让我们来看一下粗心对待transient域可能引起的潜在问题。假设我们修改了类定义,提供给transient域一个默认值,
代码如下:
public class GuestLoggingInfo implements java.io.Serializable
{
private Date loggingDate = new Date();
private String uid;
private transient String pwd;
GuestLoggingInfo()
{
uid = "guest";
pwd = "guest";
}
public String toString()
{
//same as above
}
}
现在,如果我们穿行化GuestLoggingInfo的一个实例,将它写入磁盘,并且再将它从磁盘中读出,我们仍然看到读回的对象打印password 为
"
NOT SET
"
。当从磁盘中读出某个类的实例时,实际上并不会执行这个类的构造函数,而是载入了一个该类对象的持久化状态,并将这个状态赋值给该类的另一个对象。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
java关键字
Volatile:
Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到主内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。
分享到:
相关推荐
### Java关键字总结 Java是一种广泛使用的面向对象编程语言,它具备简单性、可移植性、高性能等特点。在Java中,关键字具有特殊的语法含义,不能用作标识符(例如变量名或方法名)。以下是对给定文件中提到的Java...
### Java中的transient关键字详解 在Java编程语言中,`transient`关键字是一个非常重要的概念,主要用于对象序列...同时,理解`transient`与`volatile`之间的区别也是处理复杂Java应用中的多线程和序列化问题的关键。
这篇文档《Java关键字详细解》将深入探讨Java中的关键字及其用途。 首先,我们来看看Java中的主要关键字。`public`、`private`、`protected`是访问修饰符,用于控制类、方法和变量的访问权限。`public`可以被任何...
### Java关键字详解 #### 概述 Java是一种广泛使用的面向对象编程语言,它拥有丰富的关键字集,用于控制程序的行为和结构。Java关键字是由Java语言预定义的标识符,具有特殊的含义,不能用作变量名、方法名或类名等...
Java关键字是编程的基础,它们是Java语言预定义的标识符,具有特殊含义并被Java编译器识别。在Java中,一共有51个关键字(包括保留字),但描述中提到的是48个,可能是因为某些关键字在特定上下文不常用或者被归类到...
Java关键字和命名规范是Java编程语言中的基础概念,它们对于编写清晰、规范的代码至关重要。Java关键字是Java语言内置的、具有特殊用途的保留字,而命名规范则是关于如何给类、方法、变量等命名的约定。 ### Java...
下面是对Java关键字的详细解释: 1. `abstract`: 用于定义抽象类或抽象方法,表示类或方法没有具体实现,需要子类进行具体实现。 2. `boolean`: 表示逻辑值,只有两个可能的值,`true` 和 `false`。 3. `break`: ...
Java 共有 50 多个关键字,它们包括但不限于 `abstract`、`assert`、`boolean`、`break`、`byte`、`case`、`catch`、`char`、`class`、`const`(虽然未使用)、`continue`、`default`、`do`、`double`、`else`、`...
### Java关键字详解 #### 前言 Java作为一种广泛使用的编程语言,在软件开发领域占据了重要的地位。Java的关键字,即保留字,是Java语言中具有特殊意义的标识符,它们预定义并保留用于语言本身的语法结构。理解这些...
Java关键字是编程的基础,它们是Java语言预定义的标识符,具有特定的含义和功能,不能用作变量名、方法名或类名。在Java中,关键字是保留给编译器使用的,它们对于理解程序的结构和控制流程至关重要。本文将深入探讨...
修饰符如`private`, `public`, `protected`定义了访问权限,`final`, `static`, `abstract`, `native`, `synchronized`, `volatile`, `strictfp`, `transient`分别用于定义不可变对象、静态成员、抽象方法、本地方法...
Java关键字是编程的基础,它们是Java语言预定义的、具有特殊含义的标识符,不能作为变量名、方法名或类名。以下是对50个Java关键字的详细解释: 1. **abstract**:用于声明抽象类或抽象方法,不包含具体实现。 2. ...
这只是Java关键字的一部分,其他关键字如`enum`, `final`, `float`, `goto`, `instanceof`, `new`, `package`, `super`, `synchronized`, `this`, `throw`, `throws`, `transient`, `volatile`等也有着各自的重要...
在Java编程语言中,关键字是具有特殊...以上是Java关键字的全面总结,它们在编写Java程序时扮演着至关重要的角色,帮助开发者构建各种功能和控制程序流程。了解和熟练使用这些关键字是成为一名合格的Java程序员的基础。
- `public`, `private`, `protected`, `static`, `final`, `abstract`, `synchronized`, `volatile`, `transient`:这些关键字用于定义访问级别和修饰符。 - `try`, `catch`, `finally`, `throw`, `throws`:这些...
Java关键字中也包含了用于异常处理的关键字,例如try、catch、finally,它们用于捕获异常并进行处理,以及throw和throws用于抛出异常。这些关键字的使用保证了Java程序在面对错误和异常情况时能够更加稳定和可靠地...
### Java关键字的用法 Java作为一种广泛使用的编程语言,拥有丰富的关键字来支持其核心功能与特性。本文将详细介绍部分重要的Java关键字及其用法。 #### 1. `abstract` `abstract`关键字用于定义抽象类或抽象方法...
10. 内存管理关键字:`transient`用于标记字段不序列化,`volatile`保证多线程环境中的可见性和有序性。 通过深入理解和熟练运用这些关键字,开发者可以编写出高效、稳定的Java程序。在学习过程中,结合实际案例来...
### Java关键字详解 #### Abstract `abstract` 是Java中的一个关键字,用于定义抽象类或抽象方法。抽象类是不能被实例化的类,主要用于提供子类一个基础模板,并强制子类去实现某些特定的方法。抽象方法是没有实现...
`throws`, `instanceof`, `transient`, `volatile`, `interface`, `package`, `import`, `enum`, `default`, `assert` 等,它们都在构建 Java 程序时起着不可或缺的作用。理解和熟练掌握这些关键字是成为一个优秀的...