新来个技术总监:谁在用isXxx形式定义布尔类型年后不用来了
△Hollis, 一個(gè)對(duì)Coding有著獨(dú)特追求的人△
這是Hollis的第?384?篇原創(chuàng)分享
作者 l Hollis
來源 l Hollis(ID:hollischuang)
在日常開發(fā)中,我們會(huì)經(jīng)常要在類中定義布爾類型的變量,比如在給外部系統(tǒng)提供一個(gè)RPC接口的時(shí)候,我們一般會(huì)定義一個(gè)字段表示本次請(qǐng)求是否成功的。
關(guān)于這個(gè)”本次請(qǐng)求是否成功”的字段的定義,我見過很多不同的開發(fā)者,定義的方式都不同,尤其是在屬性的命名上,有人用 success,有人用 isSuccess 表示。
從語義上面來講,兩種命名方式都可以講的通,并且也都沒有歧義。那么還有什么原則可以參考來讓我們做選擇呢。
根據(jù)JavaBeans Specification規(guī)定,如果是普通的參數(shù)propertyName,要以以下方式定義其setter/getter:
public?<PropertyType>?get<PropertyName>();public?void?set<PropertyName>(<PropertyType>?a);但是,布爾類型的變量propertyName則是單獨(dú)定義的:
public?boolean?is<PropertyName>();public?void?set<PropertyName>(boolean?m);success方法的 getter 應(yīng)該是isSuccess/getSuccess,而isSuccess的getter 應(yīng)該是isIsSuccess/getIsSuccess。
但是很多人,在使用isSuccess作為屬性名的時(shí)候,還是會(huì)采用isSuccess/getSuccess作為 getter 方法名,尤其是現(xiàn)在的很多 IDE 在默認(rèn)生成 getter 的時(shí)候也是會(huì)生成isSuccess。
在一般情況下,其實(shí)是沒有影響的。但是有一種特殊情況就會(huì)有問題,那就是發(fā)生序列化的時(shí)候可能會(huì)導(dǎo)致參數(shù)轉(zhuǎn)換異常。
我們先來定義一個(gè) 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";}}在這個(gè) JavaBean 中,有一個(gè)成員變量isSuccess,三個(gè)方法,分別是IDE幫我們自動(dòng)生成的isSuccess和setSuccess,另外一個(gè)是作者自己增加的一個(gè)符合getter命名規(guī)范的方法。
我們分別使用不同的 JSON 序列化工具來對(duì)這個(gè)類的對(duì)象進(jìn)行序列化和反序列化:
public?class?BooleanMainTest?{public?static?void?main(String[]?args)?throws?IOException?{//定一個(gè)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));}}以上代碼輸出結(jié)果:
Serializable?Result?With?fastjson?:{"hollis":"hollischuang","success":true}Serializable?Result?With?Gson?:{"isSuccess":true}Serializable?Result?With?jackson?:{"success":true,"hollis":"hollischuang"}在fastjson和jackson的結(jié)果中,原來類中的isSuccess字段被序列化成success,并且其中還包含hollis值。而Gson中只有isSuccess字段。
我們可以得出結(jié)論:fastjson和jackson在把對(duì)象序列化成json字符串的時(shí)候,是通過反射遍歷出該類中的所有g(shù)etter方法,得到getHollis和isSuccess,然后根據(jù)JavaBeans規(guī)則,他會(huì)認(rèn)為這是兩個(gè)屬性hollis和success的值。直接序列化成json:
{“hollis”:”hollischuang”,”success”:true}但是Gson并不是這么做的,他是通過反射遍歷該類中的所有屬性,并把其值序列化成json:
{“isSuccess”:true}可以看到,由于不同的序列化工具,在進(jìn)行序列化的時(shí)候使用到的策略是不一樣的,所以,對(duì)于同一個(gè)類的同一個(gè)對(duì)象的序列化結(jié)果可能是不同的。那么,如果我們把一個(gè)對(duì)象使用fastjson進(jìn)行序列化,再使用Gson反序列化會(huì)發(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));}}以上代碼,輸出結(jié)果:
Model[isSuccess=false]這和我們預(yù)期的結(jié)果完全相反,原因是因?yàn)镴SON框架通過掃描所有的getter后發(fā)現(xiàn)有一個(gè)isSuccess方法,然后根據(jù)JavaBeans的規(guī)范,解析出變量名為success,把model對(duì)象序列化城字符串后內(nèi)容為{"success":true}。
根據(jù){"success":true}這個(gè)json串,Gson框架在通過解析后,通過反射尋找Model類中的success屬性,但是Model類中只有isSuccess屬性,所以,最終反序列化后的Model類的對(duì)象中,isSuccess則會(huì)使用默認(rèn)值false。
但是,一旦以上代碼發(fā)生在生產(chǎn)環(huán)境,這絕對(duì)是一個(gè)致命的問題。
所以,作為開發(fā)者,我們應(yīng)該想辦法盡量避免這種問題的發(fā)生。
所以,建議大家使用success而不是 isSuccess 這種形式。這樣,該類里面的成員變量時(shí)success,getter方法是isSuccess,這是完全符合JavaBeans規(guī)范的。無論哪種序列化框架,執(zhí)行結(jié)果都一樣。就從源頭避免了這個(gè)問題。
技術(shù)交流群
最近有很多人問,有沒有讀者交流群,想知道怎么加入。
最近我創(chuàng)建了一些群,大家可以加入。交流群都是免費(fèi)的,只需要大家加入之后不要隨便發(fā)廣告,多多交流技術(shù)就好了。
目前創(chuàng)建了多個(gè)交流群,全國交流群、北上廣杭深等各地區(qū)交流群、面試交流群、資源共享群等。
有興趣入群的同學(xué),可長按掃描下方二維碼,一定要備注:全國 Or 城市 Or 面試 Or 資源,根據(jù)格式備注,可更快被通過且邀請(qǐng)進(jìn)群。
▲長按掃描
往期推薦為什么不建議你用去 “! = null” 做判空?
37歲程序員被裁,120天沒找到工作,無奈去小公司,結(jié)果懵了...
北大韋神透露現(xiàn)狀:自己課講得不太好,中期學(xué)生退課后就剩下5、6個(gè)人...
如果你喜歡本文,
請(qǐng)長按二維碼,關(guān)注?Hollis.
轉(zhuǎn)發(fā)至朋友圈,是對(duì)我最大的支持。
點(diǎn)個(gè)?在看?
喜歡是一種感覺
在看是一種支持
↘↘↘
總結(jié)
以上是生活随笔為你收集整理的新来个技术总监:谁在用isXxx形式定义布尔类型年后不用来了的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 五分钟,手撸一个Spring容器!
- 下一篇: 电脑键盘练习_三款神器!超越键盘飞毛腿!