# Java 瞬态与静态变量
> 原文: [https://javabeginnerstutorial.com/core-java-tutorial/transient-vs-static-variable-java/](https://javabeginnerstutorial.com/core-java-tutorial/transient-vs-static-variable-java/)
在这里,我将向您展示静态和瞬态之间的区别。 无论如何,这两件事在范围上是完全不同的,但是人们经常会问我这个问题。 在本文的这篇文章中,我将尝试对其进行解释。 在之前的文章中,您可以在此处单击[(第一部分)](https://javabeginnerstutorial.com/core-java-tutorial/java-serialization-concept-example/ "Java serialization concept and Example"),在此处单击[以获取(第二部分)](https://javabeginnerstutorial.com/core-java-tutorial/java-serialization-concept-example-part-ii/ "Java serialization concept and Example Part II")。
## 静态变量
静态变量属于一个类,而不属于任何单个实例。 序列化的概念与对象的当前状态有关。 仅与类的特定实例关联的数据被序列化,因此静态成员字段在序列化过程中将被忽略。
## 瞬态变量
如果您不想保存变量的状态,请在序列化时使用。 您必须将该变量标记为`Transient`。 环境将知道应忽略此变量,并且不会保存相同的值。
> 即使概念是完全不同的,并且不进行储蓄的原因也不同,人们仍然对两者的存在感到困惑。 与这两种情况一样,变量值将不会保存。
## 两者之间的区别
源代码:注意每个代码更改。
`Employee.java`
```java
package com.jbt;
import java.io.Serializable;
public class Employee extends superEmployee {
public String firstName;
private static final long serialVersionUID = 5462223600l;
}
class superEmployee implements Serializable{
public String lastName;
static String companyName;
transient String address;
static transient String companyCEO;
}
```
`SerializaitonClass.java`
```java
package com.jbt;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializaitonClass {
public static void main(String[] args) {
Employee emp = new Employee();
emp.firstName = "Vivekanand";
emp.lastName = "Gautam";
emp.companyName = "JBT";
//Below part needs to be removed in case address field is made final
emp.address = "MUM";
emp.companyCEO = "ME CEO";
try {
FileOutputStream fileOut = new FileOutputStream("./employee.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(emp);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in ./employee.txt file");
} catch (IOException i) {
i.printStackTrace();
}
}
}
```
`DeserializationClass.java`
```java
package com.jbt;
import java.io.*;
public class DeserializationClass {
public static void main(String[] args) {
Employee emp = null;
try {
FileInputStream fileIn = new FileInputStream("./employee.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
emp = (Employee) in.readObject();
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserializing Employee...");
System.out.println("First Name of Employee: " + emp.firstName);
System.out.println("Last Name of Employee: " + emp.lastName);
System.out.println("Company Name: "+emp.companyName);
System.out.println("Company CEO: "+emp.companyCEO);
System.out.println("Company Address: "+emp.address);
}
}
```
首先执行“`SerializaitonClass`”,您将获得以下输出。
```java
Serialized data is saved in ./employee.txt file
```
其次,执行“`DeserializationClass`”,您将获得以下输出
```java
Deserializing Employee...
First Name of Employee: Vivekanand
Last Name of Employee: Gautam
Company Name: null
Company CEO: null
Company Address: null
```
从输出中可以看到,只有姓氏值被保存。 静态和瞬态变量值均未保存。
现在,我将稍作更改代码,看看会发生什么。
`Employee.java`
```java
package com.jbt;
import java.io.Serializable;
public class Employee extends superEmployee {
public String firstName;
private static final long serialVersionUID = 5462223600l;
}
class superEmployee implements Serializable {
public String lastName;
/*
* Here i am providing the value of company name,companyCEO and address
* while defining these variables.
*/
static String companyName = "TATA";
transient String address = "DEL";
static transient String companyCEO = "Jayshree";
}
```
再次执行相同的代码并查看输出
```java
Deserializing Employee...
First Name of Employee: Vivekanand
Last Name of Employee: Gautam
Company Name: TATA
Company CEO: Jayshree
Company Address: null
```
非常仔细地查看输出。 此处已保存`companyName`,`companyCEO`的值,但未保存地址的值。 另外,检查这些变量的保存值。
```java
Company Name: TATA
Company CEO: Jayshree
```
在这两种情况下,此处存储的`case`值均来自类(`Employee`类),而不是对象(`emp`对象)。 此外,即使是临时变量,也会保存`companyCEO`变量值。 因为`static`修饰符会更改此变量的行为。
## 重点
1. 静态变量无法序列化。
2. 在反序列化时,如果在基类的初始化过程中提供了相同的值,则可用于静态变量。
* 这并不意味着静态变量将被序列化。 这仅意味着静态变量将使用相同的值初始化,并在加载类时分配(在这种情况下为`TATA`)。 如果之前未加载类(新 JVM)。 请注意示例代码。
* 如果类已经在 JVM 中加载并且静态变量值已更改,那么将显示更改后的值。
3. 如果将变量定义为“静态”和“瞬态”,则静态修饰符将控制变量的行为,而不是瞬态。
* 静态和瞬态是不同的。 在某些情况下,它们的行为看起来相同,但并非总是如此。 如果在加载类时为变量分配了一个值,则在反序列化类时该值将分配给静态变量,而不是瞬时的。 因此,如果您同时使用这两个修饰符和变量,那么从某种意义上来说,我要说的是静态将优先于瞬态。
4. 瞬态变量值将不会保存。 同样,在反序列化过程中不能为其分配任何值。 这与静态行为不同。
## 最终修饰符对序列化的影响
要查看`Final`修饰符的效果,我再次更改`Employee`类的代码。
`Employee.java`
```java
package com.jbt;
import java.io.Serializable;
public class Employee extends superEmployee {
public String firstName;
private static final long serialVersionUID = 5462223600l;
}
class superEmployee implements Serializable {
public String lastName;
/*
* Here i am providing the value of company name,companyCEO and address
* while defining these variables.
* I am making address as final here
*/
static String companyName = "TATA";
transient final String address = "DEL";
static transient String companyCEO = "Jayshree";
}
```
再次执行代码,看看区别。 上面代码的输出将是
```java
Deserializing Employee...
First Name of Employee: Vivekanand
Last Name of Employee: Gautam
Company Name: TATA
Company CEO: Jayshree
Company Address: DEL
```
如您所见,序列化过程中还保存了地址字段,因为它现在是最终的。
## 接口和最终
我看到了一种情况,您可以序列化未序列化的接口内部的变量。
`Employee.java`
```java
package com.jbt;
import java.io.Serializable;
public class Employee extends superEmployee implements variableConstant{
public String firstName;
private static final long serialVersionUID = 5462223600l;
}
class superEmployee implements Serializable {
public String lastName;
/*
* Here i am providing the value of company name,companyCEO and address
* while defining these variables.
* I am making address as final here
*/
static String companyName = "TATA";
transient final String address = "DEL";
static transient String companyCEO = "Jayshree";
}
interface variableConstant {
public static final String education = "MCA";
}
```
`DeserializationClass.java`
```java
package com.jbt;
import java.io.*;
public class DeserializationClass {
public static void main(String[] args) {
Employee emp = null;
try {
FileInputStream fileIn = new FileInputStream("./employee.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
emp = (Employee) in.readObject();
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserializing Employee...");
System.out.println("First Name of Employee: " + emp.firstName);
System.out.println("Last Name of Employee: " + emp.lastName);
System.out.println("Company Name: "+emp.companyName);
System.out.println("Company CEO: "+emp.companyCEO);
System.out.println("Company Address: "+emp.address);
System.out.println("Education: "+emp.education);
}
}
```
执行以上代码,然后查看输出。
```java
Deserializing Employee...
First Name of Employee: Vivekanand
Last Name of Employee: Gautam
Company Name: TATA
Company CEO: Jayshree
Company Address: DEL
Education: MCA
```
在这里,您可以看到教育的值得以保存。 此值是接口的一部分。 但是由于这是恒定的,因此在序列化时将其保存。
I think I have covered all possible scenarios. Do let me know in case any particular scenario is not covered in this article. Feel free to say me hi, if you like this article. And yes I didn’t qualify for the interview. 😛
- JavaBeginnersTutorial 中文系列教程
- Java 教程
- Java 教程 – 入门
- Java 的历史
- Java 基础知识:Java 入门
- jdk vs jre vs jvm
- public static void main(string args[])说明
- 面向初学者的 Java 类和对象教程
- Java 构造器
- 使用 Eclipse 编写 Hello World 程序
- 执行顺序
- Java 中的访问修饰符
- Java 中的非访问修饰符
- Java 中的数据类型
- Java 中的算术运算符
- Java 语句初学者教程
- 用 Java 创建对象的不同方法
- 内部类
- 字符串构建器
- Java 字符串教程
- Java 教程 – 变量
- Java 中的变量
- Java 中的局部变量
- Java 中的实例变量
- Java 引用变量
- 变量遮盖
- Java 教程 – 循环
- Java for循环
- Java 教程 – 异常
- Java 异常教程
- 异常处理 – try-with-resources语句
- Java 异常处理 – try catch块
- Java 教程 – OOPS 概念
- Java 重载
- Java 方法覆盖
- Java 接口
- 继承
- Java 教程 – 关键字
- Java 中的this关键字
- Java static关键字
- Java 教程 – 集合
- Java 数组教程
- Java 集合
- Java 集合迭代器
- Java Hashmap教程
- 链表
- Java 初学者List集合教程
- Java 初学者的Map集合教程
- Java 初学者的Set教程
- Java 初学者的SortedSet集合教程
- Java 初学者SortedMap集合教程
- Java 教程 – 序列化
- Java 序列化概念和示例
- Java 序列化概念和示例第二部分
- Java 瞬态与静态变量
- serialVersionUID的用途是什么
- Java 教程 – 枚举
- Java 枚举(enum)
- Java 枚举示例
- 核心 Java 教程 – 线程
- Java 线程教程
- Java 8 功能
- Java Lambda:初学者指南
- Lambda 表达式简介
- Java 8 Lambda 列表foreach
- Java 8 Lambda 映射foreach
- Java 9
- Java 9 功能
- Java 10
- Java 10 独特功能
- 核心 Java 教程 – 高级主题
- Java 虚拟机基础
- Java 类加载器
- Java 开发人员必须知道..
- Selenium 教程
- 1 什么是 Selenium?
- 2 为什么要进行自动化测试?
- 3 Selenium 的历史
- 4 Selenium 工具套件
- 5 Selenium 工具支持的浏览器和平台
- 6 Selenium 工具:争霸
- 7A Selenium IDE – 简介,优点和局限性
- 7B Selenium IDE – Selenium IDE 和 Firebug 安装
- 7C Selenium IDE – 突破表面:初探
- 7D Selenium IDE – 了解您的 IDE 功能
- 7E Selenium IDE – 了解您的 IDE 功能(续)。
- 7F Selenium IDE – 命令,目标和值
- 7G Selenium IDE – 记录和运行测试用例
- 7H Selenium IDE – Selenium 命令一览
- 7I Selenium IDE – 设置超时,断点,起点
- 7J Selenium IDE – 调试
- 7K Selenium IDE – 定位元素(按 ID,名称,链接文本)
- 7L Selenium IDE – 定位元素(续)
- 7M Selenium IDE – 断言和验证
- 7N Selenium IDE – 利用 Firebug 的优势
- 7O Selenium IDE – 以所需的语言导出测试用例
- 7P Selenium IDE – 其他功能
- 7Q Selenium IDE – 快速浏览插件
- 7Q Selenium IDE – 暂停和反射
- 8 给新手的惊喜
- 9A WebDriver – 架构及其工作方式
- 9B WebDriver – 在 Eclipse 中设置
- 9C WebDriver – 启动 Firefox 的第一个测试脚本
- 9D WebDriver – 执行测试
- 9E WebDriver – 用于启动其他浏览器的代码示例
- 9F WebDriver – JUnit 环境设置
- 9G WebDriver – 在 JUnit4 中运行 WebDriver 测试
- 9H WebDriver – 隐式等待
- 9I WebDriver – 显式等待
- 9J WebDriver – 定位元素:第 1 部分(按 ID,名称,标签名称)
- 9K WebDriver – 定位元素:第 2 部分(按className,linkText,partialLinkText)
- 9L WebDriver – 定位元素:第 3a 部分(按cssSelector定位)
- 9M WebDriver – 定位元素:第 3b 部分(cssSelector续)
- 9N WebDriver – 定位元素:第 4a 部分(通过 xpath)
- 9O WebDriver – 定位元素:第 4b 部分(XPath 续)
- 9P WebDriver – 节省时间的捷径:定位器验证
- 9Q WebDriver – 处理验证码
- 9R WebDriver – 断言和验证
- 9S WebDriver – 处理文本框和图像
- 9T WebDriver – 处理单选按钮和复选框
- 9U WebDriver – 通过两种方式选择项目(下拉菜单和多项选择)
- 9V WebDriver – 以两种方式处理表
- 9W WebDriver – 遍历表元素
- 9X WebDriver – 处理警报/弹出框
- 9Y WebDriver – 处理多个窗口
- 9Z WebDriver – 最大化窗口
- 9AA WebDriver – 执行 JavaScript 代码
- 9AB WebDriver – 使用动作类
- 9AC WebDriver – 无法轻松定位元素? 继续阅读...
- 10A 高级 WebDriver – 使用 Apache ANT
- 10B 高级 WebDriver – 生成 JUnit 报告
- 10C 高级 WebDriver – JUnit 报表自定义
- 10D 高级 WebDriver – JUnit 报告自定义续
- 10E 高级 WebDriver – 生成 PDF 报告
- 10F 高级 WebDriver – 截屏
- 10G 高级 WebDriver – 将屏幕截图保存到 Word 文档
- 10H 高级 WebDriver – 发送带有附件的电子邮件
- 10I 高级 WebDriver – 使用属性文件
- 10J 高级 WebDriver – 使用 POI 从 excel 读取数据
- 10K 高级 WebDriver – 使用 Log4j 第 1 部分
- 10L 高级 WebDriver – 使用 Log4j 第 2 部分
- 10M 高级 WebDriver – 以无头模式运行测试
- Vue 教程
- 1 使用 Vue.js 的 Hello World
- 2 模板语法和反应式的初探
- 3 Vue 指令简介
- 4 Vue Devtools 设置
- 5 数据绑定第 1 部分(文本,原始 HTML,JavaScript 表达式)
- 6 数据绑定第 2 部分(属性)
- 7 条件渲染第 1 部分(v-if,v-else,v-else-if)
- 8 条件渲染第 2 部分(v-if和v-show)
- 9 渲染列表第 1 部分(遍历数组)
- 10 渲染列表第 2 部分(遍历对象)
- 11 监听 DOM 事件和事件修饰符
- 12 监听键盘和鼠标事件
- 13 让我们使用简写
- 14 使用v-model进行双向数据绑定
- 15 表单输入绑定
- 18 类绑定
- Python 教程
- Python 3 简介
- Python 基础知识 - 又称 Hello World 以及如何实现
- 如何在 Windows 中安装 python
- 适用于 Windows,Mac,Linux 的 Python 设置
- Python 数字和字符串
- Python 列表
- Python 集
- Python 字典
- Python 条件语句
- Python 循环
- Python 函数
- 面向对象编程(OOP)
- Python 中的面向对象编程
- Python 3 中的异常处理
- Python 3:猜数字
- Python 3:猜数字 – 回顾
- Python 生成器
- Hibernate 教程
- Hibernate 框架基础
- Hibernate 4 入门教程
- Hibernate 4 注解配置
- Hibernate 4 的实体关系
- Hibernate 4 中的实体继承模型
- Hibernate 4 查询语言
- Hibernate 4 数据库配置
- Hibernate 4 批处理
- Hibernate 4 缓存
- Hibernate 4 审计
- Hibernate 4 的并发控制
- Hibernate 4 的多租户
- Hibernate 4 连接池
- Hibernate 自举