你的JavaBean是否真的需要實現Serializable


眾所周知

如果一個對象需要進行網絡傳輸,那么該對象就需要實現Serializable接口,為了防止反序列失敗,該對象需提供一個默認的serialVersionUID(該值在反序列化的時候會進行校驗校驗失敗並拋出InvalidClassException異常)。

提出疑問

現在需要將一個對象返回給前端,那么該對象是否需要實現 Serializable接口,並提供一個默認的serialVersionUID?如果不實現會有什么影響?

探索

我們現在想一個問題,現在一般前后端進行數據交互一般都是json格式的數據,那么是誰在什么時候將我們的對象轉換成json格式的?只要想明白這個問題,也就解決了我們提出的疑問。

這里我先用SpringMVC框架做一番解釋,我們使用SpringMVC框架的時候如果要返回一個json串給前端只需要將對象返回並且在方法上加上@ResponseBody注解,類似以下操作

 

SpirngMVC是什么類在什么時候處理@ResponseBody

SpringMVC 中處理@ResponseBody主要是通過類RequestResponseBodyMethodProcessor#handleReturnValue處理返回值,解析成json又涉及到的HttpMessageConverter的配置,其實正常情況下SpringMVC是自動幫我們配置以下轉換器:

ByteArrayHttpMessageConverter,

StringHttpMessageConverter,

ResourceHttpMessageConverter,

SourceHttpMessageConverter,

AllEncompassingFormHttpMessageConverter,

是否引入jackson包配置MappingJackson2HttpMessageConverter。

具體詳見WebMvcConfigurationSupport#addDefaultHttpMessageConverters。一般執行解析操作的是MappingJackson2HttpMessageConverter這個類,其實這個類不是干實事的,具體操作還得交給ObjectMapper這個類取實現。而ObjectMapper就是jackson包中的一個類。

jackson是怎么將對象轉換成json

jackson將對象解析成json的入口是ObjectMapper#writeValueAsString,其內部實現大概是先初始化一個4000容量的WriterBasedJsonGenerator#_outputBuffer char數組,然后將對象中的字段一一往char數組中放入,最后將char數組轉換成String。具體詳見ObjectMapper#writeValueAsString,因此對象轉換成json與Serializable無關。

驗證

這里主要驗證對象返回是否與Serializable有關系,如果一個對象進行序列化跟實現Serializable有關系的話,那么序列化的過程中一定就會調用該對象下的writeObject(java.io.ObjectOutputStream s) ,因此只需啟動程序調用接口,在方法writeObject上打斷點,看是否可以攔截住。這里使用HashSet做實驗。會發現斷點沒有停住。說明使用SpringMVC框架返回給前端的對象無需實現Serializable接口。其大致圖如下

 

因此真正與網絡傳輸打交道的是SpringMVC轉換后的json字符串,實體對象與網絡並沒用直接的接觸,所以這里的實體對象無需實現Serializable接口。

什么時候需要實現Serializable接口

還是那句話,如果你的對象需要網絡傳輸或者持久化(對象直接轉換為字節的形式傳輸),只要你的對象需要轉換為字節的形式那么你的對象就要實現Serializable接口。比如使用dubbo使用rpc的方式調用接口,那么接口參數就一定要實現Serializable接口。

總結

一般來說如果你的對象需要網絡傳輸或者持久化(對象直接轉換為字節的形式傳輸),那么就需要實現Serializable接口。如果只是轉換為字符串的形式與網絡打交道,那么就不需要實現Serializable接口。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM