Java中的transient關(guān)鍵字解析
transient關(guān)鍵字
java對象在實現(xiàn)了Serilizable接口后這個對象就可以被序列化,但是java的這種序列化機制會將這個類的所有屬性和方法都序列化.有時候我們的一些敏感信息比如密碼并不想序列化傳輸給對方,這個時候transient關(guān)鍵字就派上用場了,如果一個類的變量加上了transient關(guān)鍵字那么這個字段就不會被序列化
下面這個例子我們利用transient避免User序列化過程中密碼字段的序列化
@Data @ToString @AllArgsConstructor public class User implements Serializable { private String username; private transient String password; }
我們首先創(chuàng)建一個對象User,利用ObjectOutputStream序列化到本地文件,利用ObjectInputStream讀取并反序列化為User對象
try (ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("user.txt")); ObjectInputStream is = new ObjectInputStream(new FileInputStream("user.txt"));) { User user = new User("jack", "123456"); System.out.println(user); os.writeObject(user); os.flush(); user = (User) is.readObject(); System.out.println(user); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }
運行結(jié)果如下
User{username='jack', password='123456'}
User{username='jack', password='null'}
可以看到密碼字段為空
從上面這個例子可以看到一旦變量被transient關(guān)鍵字修飾,該變量就不參與持久化過程,再進一步深入學習transient
1. transient關(guān)鍵字只能修飾變量,不能修飾方法和類.如果變量類型是我們自定義的類,那么這個類需要實現(xiàn)Serializable接口
2. 靜態(tài)變量無論是否被transient關(guān)鍵字修飾都不參與序列化
接下來我們詳細講解下上述的第二點 我們給User添加一個字段Country,這是一個靜態(tài)字段
我們重試上面的過程
try (ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("user.txt")); ObjectInputStream is = new ObjectInputStream(new FileInputStream("user.txt"));) { User user = new User("jack", "123456"); User.setCountry("China"); System.out.println(user); os.writeObject(user); os.flush(); user = (User) is.readObject(); System.out.println(user); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }
與第一個例子不同點在于我們在利用setter設(shè)置Country
運行結(jié)果
User{username='jack', password='123456', country='China'}
User{username='jack', password='null', country='China'}
我們發(fā)現(xiàn)country好像被序列化了,但是靜態(tài)變量無論如何都不參與初始化的,我們猜想country中的值是jvm中的而不是反序列化出來的 我們利用下面這個例子驗證我們的猜想
try (ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("user.txt")); ObjectInputStream is = new ObjectInputStream(new FileInputStream("user.txt"));) { User user = new User("jack", "123456"); User.setCountry("China"); System.out.println(user); os.writeObject(user); os.flush(); User.setCountry("American"); user = (User) is.readObject(); System.out.println(user); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }
對象序列化寫入文件后我們再修改User的country字段為American
結(jié)果如下
User{username='jack', password='123456', country='China'}
User{username='jack', password='null', country='American'}
可以看到country果然變成了American我們的猜想成立,也就是說反序列化后static型變量的值為JVM中的值
還有一點關(guān)于transient關(guān)鍵字失靈的情況需要注意,看下面這個例子
@ToString @AllArgsConstructor @NoArgsConstructor public class Student implements Externalizable { private transient String username; private transient int age; private transient String fatherName; @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(username); out.writeInt(age); out.writeObject(fatherName); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { username = (String) in.readObject(); age = in.readInt(); fatherName= (String) in.readObject(); } }
student學生類實現(xiàn)了Externalizable接口作用我們下面再講,student的所有屬性都使用transient關(guān)鍵字修飾
測試代碼如下
try (ObjectInput in = new ObjectInputStream(new FileInputStream(new File("student.txt"))); ObjectOutput out = new ObjectOutputStream(new FileOutputStream(new File("student.txt")));) { Student student = new Student("student", 20, "father"); System.out.println(student); out.writeObject(student); out.flush(); student = (Student) in.readObject(); System.out.println(student); } catch (Exception e) { e.printStackTrace(); }
運行結(jié)果如下所示
Student(username=student, age=20, fatherName=father)
Student(username=student, age=20, fatherName=father)
可以看到盡管transient關(guān)鍵字修飾了所有屬性,按理這些屬性都不應該被序列化,這是為什么呢,這要談到j(luò)ava的序列化機制了,java自帶的對象的序列化可以通過兩種方法實現(xiàn),一種就是Serializable,另外一種就是上面的Externalizable,利用External自定義java序列化方式,選擇序列化哪些屬性都與transient關(guān)鍵字無關(guān)了
到此這篇關(guān)于Java中的transient關(guān)鍵字解析的文章就介紹到這了,更多相關(guān)Java中的 transient內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 靜態(tài)數(shù)據(jù)初始化的示例代碼
這篇文章主要介紹了Java 靜態(tài)數(shù)據(jù)初始化的示例代碼,幫助大家更好的理解和學習Java,感興趣的朋友可以了解下2020-09-09SpringBoot 項目如何在tomcat容器中運行的實現(xiàn)方法
這篇文章主要介紹了SpringBoot 項目如何在tomcat容器中運行的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-09-09Spring Boot 工程的創(chuàng)建和運行(圖文)
這篇文章主要介紹了Spring Boot 工程的創(chuàng)建和運行(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02ruoyi-springboot框架新增模塊調(diào)接口報404的解決方案
這篇文章主要介紹了ruoyi-springboot框架新增模塊調(diào)接口報404的解決方案,文中通過代碼示例給大家講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-03-03SpringBoot整合FastDFS中間件實現(xiàn)文件分布管理
FastDFS是一個開源的輕量級分布式文件系統(tǒng),它對文件進行管理,功能包括:文件存儲、文件同步、文件上傳、文件下載等,解決了大容量存儲和負載均衡的問題,本文介紹了SpringBoot整合FastDFS中間件實現(xiàn)文件分布管理,需要的朋友可以參考下2024-08-08