# 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 自舉