<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          新來個技術總監(jiān):誰在用isXxx形式定義布爾類型年后不用來了

          共 3761字,需瀏覽 8分鐘

           ·

          2022-01-19 11:11

          △Hollis, 一個對Coding有著獨特追求的人△
          這是Hollis的第?384?篇原創(chuàng)分享
          作者 l Hollis
          來源 l Hollis(ID:hollischuang)

          在日常開發(fā)中,我們會經(jīng)常要在類中定義布爾類型的變量,比如在給外部系統(tǒng)提供一個RPC接口的時候,我們一般會定義一個字段表示本次請求是否成功的。

          關于這個”本次請求是否成功”的字段的定義,我見過很多不同的開發(fā)者,定義的方式都不同,尤其是在屬性的命名上,有人用 success,有人用 isSuccess 表示。

          從語義上面來講,兩種命名方式都可以講的通,并且也都沒有歧義。那么還有什么原則可以參考來讓我們做選擇呢。

          根據(jù)JavaBeans Specification規(guī)定,如果是普通的參數(shù)propertyName,要以以下方式定義其setter/getter:

          public??get();

          public?void?set(?a);

          但是,布爾類型的變量propertyName則是單獨定義的:

          public?boolean?is();

          public?void?set(boolean?m);

          success方法的 getter 應該是isSuccess/getSuccess,而isSuccess的getter 應該是isIsSuccess/getIsSuccess。

          但是很多人,在使用isSuccess作為屬性名的時候,還是會采用isSuccess/getSuccess作為 getter 方法名,尤其是現(xiàn)在的很多 IDE 在默認生成 getter 的時候也是會生成isSuccess。

          在一般情況下,其實是沒有影響的。但是有一種特殊情況就會有問題,那就是發(fā)生序列化的時候可能會導致參數(shù)轉(zhuǎn)換異常。

          我們先來定義一個 JavaBean:

          class?Model?implements?Serializable?{


          ???private?static?final?long?serialVersionUID?=?1836697963736227954L;

          ???private?boolean?isSuccess;

          ???public?boolean?isSuccess()?{

          ???????return?isSuccess;

          ???}

          ???public?void?setSuccess(boolean?success)?{

          ???????isSuccess?=?success;

          ???}

          ???public?String?getHollis(){

          ???????return?"hollischuang";

          ???}

          }

          在這個 JavaBean 中,有一個成員變量isSuccess,三個方法,分別是IDE幫我們自動生成的isSuccess和setSuccess,另外一個是作者自己增加的一個符合getter命名規(guī)范的方法。

          我們分別使用不同的 JSON 序列化工具來對這個類的對象進行序列化和反序列化:

          public?class?BooleanMainTest?{

          ?????public?static?void?main(String[]?args)?throws?IOException?{

          ?????????//定一個Model類型

          ?????????Model?model?=?new?Model();

          ?????????model.setSuccess(true);



          ?????????//使用fastjson(1.2.16)序列化model成字符串并輸出

          ?????????System.out.println("Serializable?Result?With?fastjson?:"?+?JSON.toJSONString(model));



          ?????????//使用Gson(2.8.5)序列化model成字符串并輸出

          ?????????Gson?gson?=new?Gson();

          ?????????System.out.println("Serializable?Result?With?Gson?:"?+gson.toJson(model));



          ?????????//使用jackson(2.9.7)序列化model成字符串并輸出

          ?????????ObjectMapper?om?=?new?ObjectMapper();

          ?????????System.out.println("Serializable?Result?With?jackson?:"?+om.writeValueAsString(model));

          ?????}

          }

          以上代碼輸出結果:

          Serializable?Result?With?fastjson?:{"hollis":"hollischuang","success":true}

          Serializable?Result?With?Gson?:{"isSuccess":true}

          Serializable?Result?With?jackson?:{"success":true,"hollis":"hollischuang"}

          在fastjson和jackson的結果中,原來類中的isSuccess字段被序列化成success,并且其中還包含hollis值。而Gson中只有isSuccess字段。

          我們可以得出結論:fastjson和jackson在把對象序列化成json字符串的時候,是通過反射遍歷出該類中的所有getter方法,得到getHollis和isSuccess,然后根據(jù)JavaBeans規(guī)則,他會認為這是兩個屬性hollis和success的值。直接序列化成json:

          {“hollis”:”hollischuang”,”success”:true}

          但是Gson并不是這么做的,他是通過反射遍歷該類中的所有屬性,并把其值序列化成json:

          {“isSuccess”:true}

          可以看到,由于不同的序列化工具,在進行序列化的時候使用到的策略是不一樣的,所以,對于同一個類的同一個對象的序列化結果可能是不同的。那么,如果我們把一個對象使用fastjson進行序列化,再使用Gson反序列化會發(fā)生什么呢?

          ?public?class?BooleanMainTest?{

          ?????public?static?void?main(String[]?args)?throws?IOException?{

          ?????????Model?model?=?new?Model();

          ?????????model.setSuccess(true);

          ?????????Gson?gson?=new?Gson();

          ?????????System.out.println(gson.fromJson(JSON.toJSONString(model),Model.class));

          ?????}

          ?}

          以上代碼,輸出結果:

          Model[isSuccess=false]

          這和我們預期的結果完全相反,原因是因為JSON框架通過掃描所有的getter后發(fā)現(xiàn)有一個isSuccess方法,然后根據(jù)JavaBeans的規(guī)范,解析出變量名為success,把model對象序列化城字符串后內(nèi)容為{"success":true}。

          根據(jù){"success":true}這個json串,Gson框架在通過解析后,通過反射尋找Model類中的success屬性,但是Model類中只有isSuccess屬性,所以,最終反序列化后的Model類的對象中,isSuccess則會使用默認值false。

          但是,一旦以上代碼發(fā)生在生產(chǎn)環(huán)境,這絕對是一個致命的問題。

          所以,作為開發(fā)者,我們應該想辦法盡量避免這種問題的發(fā)生。

          所以,建議大家使用success而不是 isSuccess 這種形式。這樣,該類里面的成員變量時success,getter方法是isSuccess,這是完全符合JavaBeans規(guī)范的。無論哪種序列化框架,執(zhí)行結果都一樣。就從源頭避免了這個問題。

          ?
          ?
          技術交流群

          最近有很多人問,有沒有讀者交流群,想知道怎么加入。

          最近我創(chuàng)建了一些群,大家可以加入。交流群都是免費的,只需要大家加入之后不要隨便發(fā)廣告,多多交流技術就好了。

          目前創(chuàng)建了多個交流群,全國交流群、北上廣杭深等各地區(qū)交流群、面試交流群、資源共享群等。

          有興趣入群的同學,可長按掃描下方二維碼,一定要備注:全國 Or 城市 Or 面試 Or 資源,根據(jù)格式備注,可更快被通過且邀請進群。

          ▲長按掃描



          往期推薦

          為什么不建議你用去 “! = null” 做判空?


          37歲程序員被裁,120天沒找到工作,無奈去小公司,結果懵了...


          北大韋神透露現(xiàn)狀:自己課講得不太好,中期學生退課后就剩下5、6個人...



          如果你喜歡本文,
          請長按二維碼,關注?Hollis.
          轉(zhuǎn)發(fā)至朋友圈,是對我最大的支持。

          點個?在看?
          喜歡是一種感覺
          在看是一種支持
          ↘↘↘
          瀏覽 46
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产三级久久久精品麻豆三级 | 无码国产69精品久久久久 | 成 年 人 黄 色 视频 网站 久久久 | 又爽又黄又无遮挡 | 一区二区免费在线 |