Java中transient關鍵字的作用 解析字段排除

transient關鍵字在Java中的作用是阻止某些字段被序列化。具體原因包括:1. 安全敏感信息如密碼、密鑰等不應被保存;2. 計算型字段可通過其他字段重新計算,無需存儲;3. 排除字段可減少數據大小,提高性能。此外,Static字段本身不會被序列化,因其屬于類而非對象。若需更精細控制,可通過實現externalizable接口自定義序列化邏輯,如加密或壓縮字段,并注意必須提供無參構造函數用于反序列化。

Java中transient關鍵字的作用 解析字段排除

transient關鍵字在Java中,簡單來說,就是告訴jvm,這個字段我不希望被序列化。

Java中transient關鍵字的作用 解析字段排除

解析字段排除

Java中transient關鍵字的作用 解析字段排除

transient關鍵字的主要作用是阻止對象的某些字段在序列化過程中被保存。這在很多場景下都很有用,比如:

立即學習Java免費學習筆記(深入)”;

Java中transient關鍵字的作用 解析字段排除

  • 安全敏感信息: 密碼、密鑰等敏感信息不應該被序列化到磁盤或者網絡中。
  • 計算型字段: 某些字段的值可以通過其他字段計算得到,不需要保存,在反序列化后重新計算即可。
  • 優化性能: 排除不必要的字段可以減少序列化和反序列化的大小,提高性能。

為什么需要transient?

序列化是Java中一種將對象轉換為字節流的過程,以便可以存儲到磁盤或通過網絡傳輸。默認情況下,一個對象的所有非靜態字段都會被序列化。但有些字段可能包含敏感信息,或者在反序列化后重新計算即可,沒有必要進行序列化。這時候,transient就派上用場了。

舉個例子,假設你有一個User類:

import java.io.Serializable;  public class User implements Serializable {      private String username;     private transient String password;     private int age;      public User(String username, String password, int age) {         this.username = username;         this.password = password;         this.age = age;     }      public String getUsername() {         return username;     }      public String getPassword() {         return password;     }      public int getAge() {         return age;     }      @Override     public String toString() {         return "User{" +                 "username='" + username + ''' +                 ", password='" + password + ''' +                 ", age=" + age +                 '}';     } }

在這個例子中,password字段被聲明為transient。這意味著,當User對象被序列化時,password字段的值不會被保存。反序列化后,password字段的值將是NULL(對于對象類型)或者類型的默認值(比如0對于int類型)。

transient和static的區別是什么?

static字段屬于類,而不是對象。序列化只針對對象的狀態,所以static字段無論是否被聲明為transient,都不會被序列化。簡單來說,序列化關注的是對象實例,而static字段屬于類級別,因此不在序列化的考慮范圍內。

如何自定義序列化過程?

除了使用transient,你還可以通過實現Externalizable接口來完全控制序列化和反序列化的過程。Externalizable接口繼承自Serializable接口,但它提供了writeExternal()和readExternal()方法,允許你自定義序列化和反序列化的邏輯。這給了你更大的靈活性,可以決定哪些字段需要序列化,以及如何序列化它們。

例如:

import java.io.*;  public class ExternalizableUser implements Externalizable {      private String username;     private String password;     private int age;      public ExternalizableUser() {         // 必須提供一個無參構造函數     }      public ExternalizableUser(String username, String password, int age) {         this.username = username;         this.password = password;         this.age = age;     }      public String getUsername() {         return username;     }      public String getPassword() {         return password;     }      public int getAge() {         return age;     }      @Override     public void writeExternal(ObjectOutput out) throws IOException {         // 自定義序列化邏輯         out.writeObject(username);         // 可以對密碼進行加密后再序列化         out.writeObject(encrypt(password));         out.writeInt(age);     }      @Override     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {         // 自定義反序列化邏輯         username = (String) in.readObject();         // 解密密碼         password = decrypt((String) in.readObject());         age = in.readInt();     }      private String encrypt(String password) {         // 簡單的加密示例         return new StringBuilder(password).reverse().toString();     }      private String decrypt(String encryptedPassword) {         // 簡單的解密示例         return new StringBuilder(encryptedPassword).reverse().toString();     }      @Override     public String toString() {         return "ExternalizableUser{" +                 "username='" + username + ''' +                 ", password='" + password + ''' +                 ", age=" + age +                 '}';     } }

在這個例子中,writeExternal()方法定義了如何序列化對象,readExternal()方法定義了如何反序列化對象。你可以根據需要對字段進行加密、壓縮等處理。注意,實現Externalizable接口的類必須提供一個無參構造函數,因為在反序列化時,JVM會先調用無參構造函數創建一個對象,然后再調用readExternal()方法來填充對象的狀態。

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享