馬桶Java:1.Serializable 實(shí)現(xiàn)它做什么疏魏?

馬桶??Java 上廁所就能看完的小知識! 歡迎關(guān)注晤愧、點(diǎn)贊 持續(xù)更新大莫!

我們都知道,在學(xué)習(xí)對象序列化反序列化的時候都需要實(shí)現(xiàn)一個Serializable接口
可是我們點(diǎn)進(jìn)去一看官份,這個接口長這個樣子

/
 * @author  unascribed
 * @see java.io.ObjectOutputStream
 * @see java.io.ObjectInputStream
 * @see java.io.ObjectOutput
 * @see java.io.ObjectInput
 * @see java.io.Externalizable
 * @since   1.1
 */
public interface Serializable {
}

沒錯 他是個空的只厘!

image.png

所以我們需要先搞清楚什么是序列化?
序列化的含義就是:序列化 (Serialization)是將對象的狀態(tài)信息轉(zhuǎn)換為可以存儲或傳輸?shù)男问降倪^程舅巷。
emmmm
說白了就是保存到硬盤或者其他地方進(jìn)行存儲一下羔味!
那我們不妨做個小東西實(shí)驗(yàn)一樣!爺天生傲骨钠右,就不實(shí)現(xiàn)又能怎么樣赋元?
先上代碼!

public class Person  {
//    private static final long serialVersionUID = 291613027204248679L;

    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

}
    private static void ObjectWriter() throws IOException {
        FileOutputStream fos=new FileOutputStream("D:\\IO\\Person.object");
//        對象儲存文件的規(guī)范
        ObjectOutputStream oos=new ObjectOutputStream(fos);
        oos.writeObject(new Person("Alien",21));
        oos.close();
}

當(dāng)我們點(diǎn)擊運(yùn)行飒房!他報錯了搁凸!沒實(shí)現(xiàn)Serializable !
錯誤信息如下

Exception in thread "main" java.io.NotSerializableException: it.test.domain.Person
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1185)
    at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:349)
    at it.test.domain.ObjectOutputStream_Test1.ObjectWriter(ObjectOutputStream_Test1.java:16)
    at it.test.domain.ObjectOutputStream_Test1.main(ObjectOutputStream_Test1.java:7)

這個時候!我們就可以順騰摸瓜(查看報錯信息)狠毯!找到到底是哪里導(dǎo)致程序出現(xiàn)的異常护糖!
然后我們在ObjectOutputStream.java文件中發(fā)現(xiàn)了以下代碼
節(jié)選:

 if (obj instanceof String) {
                writeString((String) obj, unshared);
            } else if (cl.isArray()) {
                writeArray(obj, desc, unshared);
            } else if (obj instanceof Enum) {
                writeEnum((Enum<?>) obj, desc, unshared);
            } else if (obj instanceof Serializable) {
                writeOrdinaryObject(obj, desc, unshared);
            } else {
            // 如果 都不符合 就會準(zhǔn)備報異常了!嚼松!
                if (extendedDebugInfo) {
                    throw new NotSerializableException(
                        cl.getName() + "\n" + debugInfoStack.toString());
                } else {
                    throw new NotSerializableException(cl.getName());
                }
            }

奧 嫡良! 他會將傳入的對象進(jìn)行判斷:是否是String?是否是枚舉?是否是數(shù)組?是否實(shí)現(xiàn)Serializable
所以 對于源碼查看 我們知道了如果他實(shí)現(xiàn)了Serializable 那么才會被處理献酗! 這就是一種標(biāo)識 寝受!
如果他以上幾種情況 (string array...)都不是!那么就會報出異常了凌摄!
原來如此羡蛾!
所以這個東西:就是一種標(biāo)識 !

不會被序列化的可怕家族锨亏!

當(dāng)然痴怨!我們的設(shè)計(jì)師不能想著所有東西被序列化,那對象中有一些參數(shù)不想被序列化!(不器予!你不想@嗽濉)我們該怎么辦呢?
他們就是 statictransient乾翔!
static 很好理解爱葵!這東西不歸對象管,當(dāng)你將屬性聲明成 static時反浓,它就投靠了類 萌丈。
你序列化ObjectStream Object!!!是對象 管我類的小弟(static)啥事?
所以被static修飾的就無法序列化了雷则!

transient 這東西就是java賦予你的神秘力量辆雾!畢竟我們不能把所有東西都設(shè)置成static,我們需要有屬于對象的 不被序列化月劈!
那么transient就登場啦 如果你不想讓他即屬于對象又不會被序列化 那么你就給屬性添加該關(guān)鍵字!

 private transient int age;

這個時候 就不會被序列化了 當(dāng)然每次反序列化都是默認(rèn)值了度迂!
但是理解歸理解!這東西在java里面代碼邏輯中到底是怎么實(shí)現(xiàn)的呢?
我們找到了ObjectStreamClass
中有如下代碼:
這個方法 上面注釋 我給大家翻譯下猜揪!

返回與給定類聲明的所有非靜態(tài)非瞬態(tài)字段相對應(yīng)的ObjectStreamFields數(shù)組惭墓。
每個ObjectStreamField都包含一個其代表的字段的Field對象。
如果沒有默認(rèn)的可序列化字段而姐,則返回NO_FIELDS

private static ObjectStreamField[] getDefaultSerialFields(Class<?> cl) {
       // 獲取到序列化對象的參數(shù)數(shù)組
       Field[] clFields = cl.getDeclaredFields();
       ArrayList<ObjectStreamField> list = new ArrayList<>();
       int mask = Modifier.STATIC | Modifier.TRANSIENT;

       for (int i = 0; i < clFields.length; i++) {
       //判斷是不是 非靜態(tài)非瞬態(tài)字段
       // 添加所有 可序列化字段 進(jìn)入ArrayList<ObjectStreamField> 然后進(jìn)行后續(xù)操作
           if ((clFields[i].getModifiers() & mask) == 0) {
               list.add(new ObjectStreamField(clFields[i], false, true));
           }
       }
       int size = list.size();
       return (size == 0) ? NO_FIELDS :
           list.toArray(new ObjectStreamField[size]);
   }

沒錯 就是在這里判斷的腊凶!
當(dāng)然!Java序列化的本質(zhì)就是將Java對象轉(zhuǎn)化成字節(jié)數(shù)組來便于存儲和傳輸?shù)?br> 這就是Java序列化一步非常重要的過程啦拴念!


這里是??Java 每周不定時更新钧萍!喜歡的小伙伴可以點(diǎn)贊關(guān)注收藏哦!我們下個文章見丈莺!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末划煮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子缔俄,更是在濱河造成了極大的恐慌弛秋,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俐载,死亡現(xiàn)場離奇詭異蟹略,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)遏佣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進(jìn)店門挖炬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人状婶,你說我怎么就攤上這事意敛∠谙铮” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵草姻,是天一觀的道長钓猬。 經(jīng)常有香客問我,道長撩独,這世上最難降的妖魔是什么敞曹? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮综膀,結(jié)果婚禮上澳迫,老公的妹妹穿的比我還像新娘。我一直安慰自己剧劝,他們只是感情好橄登,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著担平,像睡著了一般示绊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上暂论,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天面褐,我揣著相機(jī)與錄音,去河邊找鬼取胎。 笑死展哭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的闻蛀。 我是一名探鬼主播匪傍,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼觉痛!你這毒婦竟也來了役衡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤薪棒,失蹤者是張志新(化名)和其女友劉穎手蝎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俐芯,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棵介,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了吧史。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邮辽。...
    茶點(diǎn)故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吨述,到底是詐尸還是另有隱情岩睁,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布锐极,位于F島的核電站笙僚,受9級特大地震影響芳肌,放射性物質(zhì)發(fā)生泄漏灵再。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一亿笤、第九天 我趴在偏房一處隱蔽的房頂上張望翎迁。 院中可真熱鬧,春花似錦净薛、人聲如沸汪榔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痴腌。三九已至,卻和暖如春燃领,著一層夾襖步出監(jiān)牢的瞬間士聪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工猛蔽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留剥悟,地道東北人。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓曼库,卻偏偏與公主長得像区岗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子毁枯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評論 2 354