版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
阿里巴巴java開發(fā)手冊
?編程規(guī)約
?命名風(fēng)格
?1.【強(qiáng)制】代碼中的命名均不能以下劃線或美元符號(hào)開始,也不能以下劃線或美元符號(hào)結(jié)束。
?反例:_name/_name/SObject/name./name$/Object$
?2.【強(qiáng)制】代碼中的命名嚴(yán)禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。
?說明:正確的英文拼寫和語法可以讓閱讀者易于理解,避免歧義。注意,即使純拼音命名
方式也要避免采用。
?正例:alibaba/taobao/youku/hangzhou等國際通用的名稱,可視同英文。
?反例:DaZhePromotion[Hifr]/getPingfenByName()[評分]/int某變量=3
?3.【強(qiáng)制】類名使用UpperCamelCase風(fēng)格,必須遵從駝峰形式,但以下情形例外:DO/
B0/
?DTO/VO/AO
?正例:MarcoPolo/UserDO/XmlService/TcpUdpDeal/TaPromotion
?反例:macroPolo/UserDo/XMLService/TCPUDPDeal/TAPromotion
?4.【強(qiáng)制】方法名、參數(shù)名、成員變量、局部變量都統(tǒng)T$用lowerCamelCase風(fēng)格,必須遵
從駝峰形式。
?正例:localValue/getHttpMessage()/inputUserld
?5.【強(qiáng)制】常量命名全部大寫,單詞間用下劃線隔開,力求語義表達(dá)完整清楚,不要嫌名字長。
?正例:MAX_STOCK_COUNT
?反例:MAX_COUNT
?6.【強(qiáng)制】抽象類命名使用Abstract或Base開頭;異常類命名使用Exception結(jié)尾;測試
類命名以它要測試的類的名稱開始,以Test結(jié)尾。
?7.【強(qiáng)制】中括號(hào)是數(shù)組類型的一部分,數(shù)組定義如下:String1]args;
?反例:使用Stringargs口的方式來定義。
?8.【強(qiáng)制】POJO類中布爾類型的變量,者壞要加is,否則部分框架解析會(huì)引起序列化錯(cuò)誤。
?反例:定義為基本數(shù)據(jù)類型BooleanisDeleted;的屬性,它的方法也是isDeleted(),
RPC框架在反向解析的時(shí)候,“以為”對應(yīng)的屬性名稱是deleted,導(dǎo)致屬性獲取不到,
進(jìn)而拋出異常。
?9.【強(qiáng)制】包名統(tǒng)一使用〃當(dāng),點(diǎn)分隔符之間有且僅有一個(gè)自然語義的英語單詞。包名統(tǒng)一使
用
?單數(shù)形式,但是類名如果有復(fù)數(shù)含義,類名可以使用復(fù)數(shù)形式。
?正例:應(yīng)用工具類包名為com.alibaba.open.util、類名為MessageUtils(此規(guī)則參考
spring的框架結(jié)構(gòu))
?10.【強(qiáng)制】杜絕完全不規(guī)范的縮寫,避免望文不知義。
?反例:Abstractclass"縮寫"命名成AbsClass;condition"縮寫"命名成condi,此類
隨意縮寫嚴(yán)重降低了代碼的可閱讀性。
?11.【推薦】為了達(dá)到代碼自解釋的目標(biāo),任何自定義編程元素在命名時(shí),使用盡量完整的單
詞組合來表達(dá)其意。
?正例:從遠(yuǎn)程倉庫拉取代碼的類命名為PullCodeFromRemoteRepository,
?反例:變量inta;的隨意命名方式。
?12.【推薦】如果模塊、接口、類、方法使用了設(shè)計(jì)模式,在命名時(shí)冰現(xiàn)出具體模式。
?說明:將設(shè)計(jì)模式體現(xiàn)在名字中,有利于閱讀者快速理解架構(gòu)設(shè)計(jì)理念。
?正例:
publicclassOrderFactory;publicclassLoginProxy;publicclassResourceobserver;
?13.【推薦】接口類中的方法和屬性不要加任何修飾符號(hào)(public也不要加),保持代碼的簡
潔性,并加上有效的Javadoc注釋。盡量不要在接口里定義變量,如果一定要定義變量,肯定
是與接口方法相關(guān),并且是整個(gè)應(yīng)用的基礎(chǔ)常量。
?正例:接口方法簽名:voidf();
?接口基礎(chǔ)常量表示:StringCOMPANY="alibaba";
?反例:接口方法定義:publicabstractvoidf();
?說明:JDK8中接口允許有默認(rèn)實(shí)現(xiàn),那么這個(gè)default方法,是對所有實(shí)現(xiàn)類都有價(jià)值的
默認(rèn)實(shí)現(xiàn)。
?14.接口和實(shí)現(xiàn)類的命名有兩套規(guī)則:
?1)【強(qiáng)制】對于Service和DA0類,基于SOA的理念,暴露出來的服務(wù)一定是接口,
內(nèi)部的實(shí)現(xiàn)類用Impl的后皴與接口區(qū)別。
?正例:CacheServicelmpI實(shí)現(xiàn)CacheService接口。
?2)【推薦】如果是形容能力的接口名稱,取對應(yīng)的形容詞做接口名(通常是-able的形
式)。
?正例:Abstract!ranslator實(shí)現(xiàn)Translatable。
?15.【參考】枚舉類名建議帶上Enum后綴,枚舉成員名稱需要全大寫,單詞間用下劃線隔開。
?說明:枚舉其實(shí)就是特殊的常量類,且構(gòu)造方法被默認(rèn)強(qiáng)制是私有。
?正例:枚舉名字為ProcessStatusEnum的成員名稱:SUCCESS/UNKOWN.REASON.
?16.【參考】各層命名規(guī)約:
?A)Service/DAO層方法命名規(guī)約
?1)獲取單個(gè)對象的方法用get做前綴。
?2)獲取多個(gè)對象的方法用list做前綴。
?3)獲取統(tǒng)計(jì)值的方法用count做前綴。
?4)插入的方法用save/insert做前綴。
?5)刪除的方法用remove/delete做前綴。
?6)修改的方法用update做前綴。
?B)領(lǐng)域模型命名規(guī)約
?1)數(shù)據(jù)對象:xxxDO,xxx即為數(shù)據(jù)表名。
?2)數(shù)據(jù)傳輸對象:xxxDTO,xxx為業(yè)務(wù)領(lǐng)域相關(guān)的名稱。
?3)展示對象:xxxVO,xxx為網(wǎng)頁名稱。
?4)POJO是DO/DTO/BO/VO的統(tǒng)稱,禁止命名成xxxPOJO.
?常量定義
?1.【強(qiáng)制】不允許任何魔法值(即未經(jīng)定義的常量)直接出現(xiàn)在代碼中。
?反例:Stringkey="Id#taobao_"+tradeld;cache.put(key,value);
?2.【強(qiáng)制】long或者Long初始賦值時(shí),使用大寫的L,不能是小寫的I,小寫容易跟數(shù)字1
混淆,造成誤解。
?說明:Longa=21;寫的是數(shù)字的21,還是Long型的2?
?3.【推薦】不要使用一個(gè)常量類維護(hù)所有常量,按常量功能進(jìn)行歸類,分開維護(hù)。
?說明:大而全的常量類,非得使用查找功能才能定位到修改的常量,不利于理解和維護(hù)。
?正例:緩存相關(guān)常量放在類CacheConsts下;系統(tǒng)配置相關(guān)常量放在類ConfigConsts下。
?4.【推薦】常量的復(fù)用層次有五層:跨應(yīng)用共享常量、應(yīng)用內(nèi)共享常量、子工程內(nèi)共享常量、
包內(nèi)共享常量、類內(nèi)共享常量。
?1)跨應(yīng)用共享常量:放置在二方庫中,通常是clientjar中的constant目錄下。
?2)應(yīng)用內(nèi)共享常量:放置在一方庫中,通常是modules中的constant目錄下。
?反例:易懂變量也要統(tǒng)一定義成應(yīng)用內(nèi)共享常量,兩位攻城師在兩個(gè)類中分別定義了表
示是"的變量:
?類A中:publicstaticfinalStringYES="yes";
?類B中:publicstaticfinalStringYES="y";
?A.YES.equals(B.YES),預(yù)期是true,但實(shí)際返回為false,導(dǎo)致線上問題。
?3)子工程內(nèi)部共享常量:即在當(dāng)前子工程的constant目錄下。
?4)包內(nèi)共享常量:即在當(dāng)前包下單獨(dú)的constant目錄下。
?5)類內(nèi)共享常量:直接在類內(nèi)部privatestaticfinal定義。
?5.【推薦】如果變量值僅在一個(gè)范圍內(nèi)變化,且?guī)в忻Q之外的延伸屬性,定義為枚舉類。下
面正例中的數(shù)字就是延伸信息,表示星期幾。
?正例:publicEnum{MONDAY(l),TUESDAY(2),WEDNESDAY(3),THURSDAY⑷,
FRIDAY(5),SATURDAY(6),SUNDAY(7);}
?代碼格式
?1.【強(qiáng)制】大括號(hào)的使用約定。如果是大括號(hào)內(nèi)為空,則簡潔地寫成。即可,不需要換行;如
果是非空代碼塊則:
?1)左大括號(hào)前不換行。
?2)左大括號(hào)后換行。
?3)右大括號(hào)前換行。
?4)右大括號(hào)后還有else等代碼則不換行;表示終止的右大括號(hào)后必須換行。
?2.【強(qiáng)制】左小括號(hào)和字符之間不出現(xiàn)空格;同樣,右小括號(hào)和字符之間也不出現(xiàn)空格。詳見
第5條下方正例提示。
?反例:if(空格a==b空格)
?3.【強(qiáng)制】if/for/while/switch/d。等保留字與括號(hào)之間都必須加空格。
?4.【強(qiáng)制】任何二目、三目運(yùn)算符的左右兩邊都需要加一個(gè)空格。
?說明:運(yùn)算符包括賦值運(yùn)算符=、邏輯運(yùn)算符&&、加減乘除符號(hào)等。
?5.【強(qiáng)制】采用4個(gè)空格縮進(jìn),禁止使用tab字符。
?說明:如果使用tab縮進(jìn),必須設(shè)置1個(gè)tab為4個(gè)空格。IDEA設(shè)置tab為4個(gè)空格時(shí),
請勿勾選;而在中必須勾選
?Usetabcharactereclipse,insertspacesfortabso
?正例:(涉及1-5點(diǎn))
publicstaticvoidmain(String[]args){//縮進(jìn)4個(gè)空格Stringsay="hello";//運(yùn)算
符的左右必須有一個(gè)空格intflag=0;阿里巴巴Java開發(fā)手冊一禁止用于商業(yè)用途,
違者必究一5/35//關(guān)鍵詞if與括號(hào)之間必須有一個(gè)空格,括號(hào)內(nèi)的f與左括號(hào),0與
右括號(hào)不需要空格if(flag==0){System.out.println(say);}〃左大括號(hào)前加空格且
不換行;左大括號(hào)后換行if(flag==1){System.out.pnntlnCworldn);//右大括號(hào)前換
行,右大括號(hào)后有else,不用換行}else{System.out.println("ok");//在右大括號(hào)后直
接結(jié)束,則必須換行}}
?6.【強(qiáng)制】注釋的雙斜線與注釋內(nèi)容之間有且僅有一個(gè)空格。
?正例:〃注釋內(nèi)容,注意在〃和注釋內(nèi)容之間有一個(gè)空格。
?7.【強(qiáng)制】單行字符數(shù)限制不超過120個(gè),超出需要換行,換行時(shí)遵循如下原則:
?1)第二行相對第一行縮進(jìn)4個(gè)空格,從第三行開始,不再繼續(xù)縮進(jìn),參考示例。
?2)運(yùn)算符與下文一起換行。
?3)方法調(diào)用的點(diǎn)符號(hào)與下文一起換行。
?4)方法調(diào)用時(shí),多個(gè)參數(shù),需要換行時(shí),在逗號(hào)后進(jìn)行。
?5)在括號(hào)前不要換行,見反例。
?正例:
StringBuffersb=newStringBuffer();//超過120個(gè)字符的情況下,換行縮進(jìn)4個(gè)空格,
點(diǎn)號(hào)和方法名稱一起換行
sb.append("zi").append("xin")....append('huang")....append("huang")....append("
huang");
?反例:
StringBuffersb=newStringBuffer();//超過120個(gè)字符的情況下,不要在括號(hào)前換行
sb.叩pend("zi)叩pendCxin")…叩pendChuang");//參數(shù)很多的方法調(diào)用可能超過
120個(gè)字符,不要在逗號(hào)前換行methodCargsl,args2,args3,...,argsX);
?8.【強(qiáng)制】方法參數(shù)在定義和傳入時(shí),多個(gè)參數(shù)逗號(hào)后邊必須加空格。
?正例:下例中實(shí)參的七",后邊必須要有一個(gè)空格。method("a","b",k");
?9.【強(qiáng)制】IDE的textfileencoding設(shè)置為UTF-8;IDE中文件的換行符使用Unix格式,不
要使用Windows格式。
?10.【推薦】沒有必要增加若干空格來使某一行的字符與上一行對應(yīng),立置的字符對齊。
?正例:
inta=3;longb=4L;floatc=5F;StringBuffersb=newStringBuffer();
?說明:增加sb這個(gè)變量,如果需要對齊,則給a、b、c都要增加幾個(gè)空格,在變量比
較多的情況下,是一種累贅的事情。
?11.【推薦】方法體內(nèi)的執(zhí)行語句組、變量的定義語句組、不同的業(yè)務(wù)邏輯之間或者不同的語
義之間插入一個(gè)空行。相同業(yè)務(wù)邏輯和語義之間不需要插入空行。
?說明:沒有必要插入多個(gè)空行進(jìn)行隔開。
?OOP規(guī)約
?1.【強(qiáng)制】避免通過一個(gè)類的對象引用訪問此類的靜態(tài)變量或靜態(tài)方法,無謂增加編譯器解析
成本,直接用類名來訪問即可。
?2.【強(qiáng)制】所有的卷寫方法,必須加@Override注解。
?說明:getObjectO與getObject()的問題。Y是字母的0,一個(gè)是數(shù)字的0,加
?Override可以準(zhǔn)確判斷是否覆蓋成功。另外,如果在抽象類中對方法簽名進(jìn)行修改,其
實(shí)現(xiàn)類會(huì)馬上編譯報(bào)錯(cuò)。
?3.【強(qiáng)制】相同參數(shù)類型,相同業(yè)務(wù)含義,才可以使用Java的可變參數(shù),避免使用Object。
?說明:可變參數(shù)必須放置在參數(shù)列表的最后。(提倡同學(xué)們盡量不用可變參數(shù)編程)
?正例:publicUsergetllsers(Stringtype,Integer...ids){...}
?4.【強(qiáng)制】外部正在調(diào)用或者二方庫依賴的接口,不允許修改方法簽名,避免對接口調(diào)用方產(chǎn)
生影響。接口過時(shí)必須加@Deprecated注解,并清晰地說明采用的新接口或者新服務(wù)是什么。
?5.【強(qiáng)制】不能使用過時(shí)的類或方法。
?說明:.URLDecoder中的方法decode(StringencodeStr)這個(gè)方法已經(jīng)過時(shí),
應(yīng)該使用雙參數(shù)decode(Stringsource,Stringencode),接口提供方既然明確是過時(shí)接
□,那么有義務(wù)同時(shí)提供新的接口;作為調(diào)用方來說,有義務(wù)去考證過時(shí)方法的新實(shí)現(xiàn)是
什么。
?6.【強(qiáng)制】Object的equals方法容易拋空指針異常,應(yīng)使用常量或確定有值的對象來調(diào)用
equals,
?正例:"test".equals(object);
?反例:object.equals('tesf);
?說明:推薦使用java.util.Objects#equals(JDK7引入的工具類)
?7.【強(qiáng)制】所有的相同類型的包裝類對象之間值的比較,全部使用equals方法比較。
?說明:對于Integervar=?在-128至127范圍內(nèi)的賦值,Integer對象是在
IntegerCache.cache產(chǎn)生,會(huì)復(fù)用已有對象,這個(gè)區(qū)間內(nèi)的Integer值可以直接使用==
進(jìn)行判斷,但是這個(gè)區(qū)間之外的所有雌,都會(huì)在堆上產(chǎn)生,并不會(huì)復(fù)用已有對象,這是
一個(gè)大坑,推薦使用equals方法進(jìn)行判斷。
?8.關(guān)于基本數(shù)據(jù)類型與包裝數(shù)據(jù)類型的使用標(biāo)準(zhǔn)如下:
?1)【強(qiáng)制】所有的POJO類屬性必須使用包裝數(shù)據(jù)類型。
?2)【強(qiáng)制】RPC方法的返回值和參數(shù)必須使用包裝數(shù)據(jù)類型。
?3)【推薦】所有的局部變量使用基本數(shù)據(jù)類型。
?說明:POJO類屬性沒有初值是提醒使用者在需要使用時(shí),必須自己顯式地進(jìn)行賦值,任
何NPE問題,或者入庫檢查,都由使用者來保證。
?正例:數(shù)據(jù)庫的查詢結(jié)果可能是null,因?yàn)樽詣?dòng)拆箱,用基本數(shù)據(jù)類型接收有NPE風(fēng)險(xiǎn).
?反例:比如顯示成交總額漲跌情況,即正負(fù)x%,x為基本數(shù)據(jù)類型,調(diào)用的RPC服務(wù),
調(diào)用不成功時(shí),返回的是默認(rèn)值,頁面顯示為0%,這是不合理的,應(yīng)該顯示成中劃線。所
以包裝數(shù)據(jù)類型的null值,能夠表示額外的信息,如:遠(yuǎn)程調(diào)用失敗,異常退出。
?9.【強(qiáng)制】定義DO/DTO/VO等POJO類時(shí),不要設(shè)定任何屬性默認(rèn)值。
?反例:POJO類的gmtCreate默認(rèn)值為newDate();但是這個(gè)屬性在數(shù)據(jù)提取時(shí)并沒有置
入具體值,在更新其它字段時(shí)又附帶更新了此字段,導(dǎo)致創(chuàng)建時(shí)間被修改成當(dāng)前時(shí)間。
?10.【強(qiáng)制】序列化類新增屬性時(shí),請不要修改serialVersionUID字段,避免反序列失敗;如
果完全不兼容升級,避免反序列化混亂,那么請修改serialVersionUID值。
?說明:注意serialVersionUID不一致會(huì)拋出序列化運(yùn)行時(shí)異常。
?11.【強(qiáng)制】構(gòu)造方法里面禁止加入任何I業(yè)務(wù)邏輯,如果有初始化邏輯,請放在init方法中。
?12.【強(qiáng)制】POJO類必須寫toString方法。使用IDE的中工具:source>generate
toString時(shí),如果繼承了另一個(gè)POJO類,注意在前面加一下super.toString,
?說明:在方法執(zhí)行拋出異常時(shí),可以直接調(diào)用POJO的toString。方法打印其屬性值,便
于排查問題。
?13.【推薦】使用索引訪問用String的split方法得到的數(shù)組時(shí),需做最后一個(gè)分隔符后有無
內(nèi)容的檢查,否則會(huì)有拋IndexOutOfBoundsException的風(fēng)險(xiǎn)
?說明:
Stringstr="a,b,c,/;String1]ary=str.split(",");〃預(yù)期大于3,結(jié)果是3
System.out.println(ary.length);
?14.【推薦】當(dāng)一個(gè)類有多個(gè)構(gòu)造方法,或者多個(gè)同名方法,這些方法應(yīng)該按順序放置在一起,
便于閱讀,此條規(guī)則優(yōu)先于第15條規(guī)則。
?15.【推薦】類內(nèi)方法定義順序依次是:公有方法或保護(hù)方法>私有方法>getter/setter方
法。
?說明:公有方法是類的調(diào)用者和維護(hù)者最關(guān)心的方法,首屏展示最好;保護(hù)方法雖然只是
子類關(guān)心,也可能是“模板設(shè)計(jì)模式"下的核心方法;而私有方法外部一般不需要特別關(guān)
心,是一個(gè)黑盒實(shí)現(xiàn);因?yàn)槌休d的信息價(jià)值較低,所有Service和DAO的getter/setter
方法放在類體最后
?集合處理
?16.【推薦】setter方法中,參數(shù)名稱與類成員變量名稱一致,this.成員名=參數(shù)名。在
?getter/setter方法中,不要增加業(yè)務(wù)邏輯,增加排查問題的難度。
?反例:
publicIntegergetData(){if(true){returnthis.data+100;-else{returnthis.data-
100;}}
?17.【推薦】循環(huán)體內(nèi),字符串的連接方式,使用StringBuilder的叩pend方法進(jìn)行擴(kuò)展。
?說明:反編譯出的字節(jié)碼文件顯示每次循環(huán)都會(huì)new出一個(gè)StringBuilder對象,然后進(jìn)行
叩pend操作,最后通過toString方法返回String對象,造成內(nèi)存資源浪費(fèi)。
?反例:
Stringstr="start";for(inti=0;i<100;i++){str=str+"hello";}
?18.【推薦】final可以聲明類、成員變量、方法、以及本地變量,下列情況使用final關(guān)鍵字:
?1)不允許被繼承的類,如:String類。
?2)不允許修改引用的域?qū)ο?,如:POJO類的域變量。
?3)不允許被重寫的方法,如:POJO類的setter方法。
?4)不允許運(yùn)行過程中重新賦值的局部變量。
?5)避免上下文重復(fù)使用T變量,使用final描述可以強(qiáng)制重新定義一個(gè)變量,方便更好
地進(jìn)行重構(gòu)。
?19.【推薦】慎用Object的clone方法來拷貝對象。
?說明:對象的clone方法默認(rèn)是淺拷貝,若想實(shí)現(xiàn)深拷貝需要重寫clone方法實(shí)現(xiàn)屬性對
象的拷貝。
?20.【推薦】類成員與方法訪問控制從嚴(yán):
?1)如果不允許外部直接通過new來創(chuàng)建對象,那么構(gòu)造方法必須是private.
?2)工具類不允許有public或default構(gòu)造方法。
?3)類非static成員變量并且與子類共享,必須是protected.,
?4)類非static成員變量并且僅在本類使用,必須是private。
?5)類static成員變量如果僅在本類使用,必須是private.
?6)若是static成員變量,必須考慮是否為final
?7)類成員方法只供類內(nèi)部調(diào)用,必須是private,
?8)類成員方法只對繼承類公開,那么限制為protected.
?說明:任何類、方法、參數(shù)、變量,嚴(yán)控訪問范圍。過于寬泛的訪問范圍,不利于模塊解
耦。
?思考:如果是一個(gè)private的方法,想刪除就刪除,可是一個(gè)public的service方法,或
者一個(gè)public的成員變量,刪除一下,不得手心冒點(diǎn)汗嗎?變量像自己的小孩,盡量在自
己的視線內(nèi),變量作用域太大,無限制的到處跑,那么你會(huì)擔(dān)心的。
?并發(fā)處理
?1.【強(qiáng)制】獲取單例對象需要保證線程安全,其中的方法也要保證線程安全。
?說明:資源驅(qū)動(dòng)類、工具類、單例工廠類都需要注意。
?2.【強(qiáng)制】創(chuàng)建線程或線程池時(shí)請指定有意義的線程名稱,方便出錯(cuò)時(shí)回溯。
?正例:
?3.【強(qiáng)制】線程資源必須通過線程池提供,不允許在應(yīng)用中自行顯式創(chuàng)建線程。
?說明:使用線程池的好處是減少在創(chuàng)建和銷毀線程上所花的時(shí)間以及系統(tǒng)資源的開銷,解
決資源不足的問題。如果不使用線程池,有可能造成系統(tǒng)創(chuàng)建大量同類線程而導(dǎo)致消耗完
內(nèi)存或者"過度切換”的問題。
?4.【強(qiáng)制】線程池不允許使用Executors去創(chuàng)建,而是通過ThreadPoolExecutor的方式,這
樣的處理方式讓寫的同學(xué)更加明確線程池的運(yùn)行規(guī)則,規(guī)避資源耗盡的風(fēng)險(xiǎn)。
?說明:Executors返回的線程池對象的弊端如下:
?1)FixedThreadPool和SingleThreadPool:允許的請求隊(duì)列長度為
Integer.MAX_VALUE,可能會(huì)堆積大量的請求,從而導(dǎo)致00M。
?2)CachedThreadPool和ScheduledThreadPool:允許的創(chuàng)建績呈數(shù)量為
Integer.MAX.VALUE,可能會(huì)創(chuàng)建大量的線程,從而導(dǎo)致00M。
?5.【強(qiáng)制】SimpleDateFormat是線程不安全的類,一般不要定義為static變量,如果定義為
static,必須加鎖,或者使用DateUtils工具類。
?正例:注意線程安全,使用DateUtils,亦推薦如下處理:
?說明:如果是JDK8的應(yīng)用,可以使用Instant代替Date,LocalDateTime代替
Calendar,DateTimeFormatter代替SimpleDateFormat,官方給出的解釋:
simplebeautifulstrongimmutablethread-safe.
?6.【強(qiáng)制】高并發(fā)時(shí),同步調(diào)用應(yīng)該去考量鎖的性能損耗。能用無鎖數(shù)據(jù)結(jié)構(gòu),就不要用鎖;
能鎖區(qū)塊,就不要鎖整個(gè)方法體;能用對象鎖,就不要用類鎖。
?說明:盡可能使加鎖的代碼塊工作量盡可能的小,避免在鎖代碼塊中調(diào)用RPC方法。
?7.【強(qiáng)制】對多個(gè)資源、數(shù)據(jù)庫表、對象同時(shí)加鎖時(shí),需要保持一致的加鎖順序,否則可能會(huì)
造成死鎖。
?說明:線程一需要對表A、B、C依次全部加鎖后才可以進(jìn)行更新操作,那么線程二的加鎖
順序也必須是A、B、C,否則可能出現(xiàn)死鎖。
?8.【強(qiáng)制】并發(fā)修改同一記錄時(shí),避免更新丟失,需要加鎖。要么在應(yīng)用層加鎖,要么在緩存
加鎖,要么在數(shù)據(jù)庫層使用樂觀鎖,使用version作為更新依據(jù)。
?說明:如果每次訪問沖突概率小于20%,推薦使用樂觀鎖,否則使用悲觀鎖。樂觀鎖的重
試次數(shù)不得小于3次。
?9.【強(qiáng)制】多線程并行處理定時(shí)任務(wù)時(shí),Timer運(yùn)行多個(gè)TimeTask時(shí),只要其中之一沒有捕
獲拋出的異常,其它任務(wù)便會(huì)自動(dòng)終止運(yùn)行,使用ScheduledExecLtorService則沒有這個(gè)問
題。
?10.【推薦】使用CountDownLatch進(jìn)行異步轉(zhuǎn)同步操作,每個(gè)線程退出前必須調(diào)用
countDown
?方法,線程執(zhí)行代碼注意catch異常,確保countDown方法被執(zhí)行到,避免主線程無法
執(zhí)行至await方法,直到超時(shí)才返回結(jié)果。
?說明:注意,子線程拋出異常堆棧,不能在主線程try-catch到,
?11.【推薦】避免Random實(shí)例被多線程使用,雖然共享該實(shí)例是線程安全的,但會(huì)因競爭同
-seed導(dǎo)致的性能下降。
?說明:Random實(shí)例包括java.util.Random的實(shí)例或者M(jìn)ath.random()的方式。
?正例:在JDK7之后,可以直接使用APIThreadLocalRandom,而在JDK7之前,需要
編碼保證每個(gè)線程持有一個(gè)實(shí)例。
?12.【推薦】在并發(fā)場景下,通過雙重檢查鎖(double-checkedlocking)實(shí)現(xiàn)延遲初始化的
優(yōu)化問題隱患(可參考The"Double-CheckedLockingisBroken"Declaration),推薦解決方
案中較為簡單一種(適用于JDK5及以上版本),將目標(biāo)屬性聲明為volatile型。
?反例:
?13.【參考】volatile解決多線程內(nèi)存不可見問題。對于一寫多讀,是可以解決變量同步問題,
但是如果多寫,同樣無法解決線程安全問題。如果是count++操作,使用如下類實(shí)現(xiàn):
?Atomiclntegercount=newAtomiclnteger();count.addAndGet(l);如果是JDK8,推
薦使用LongAdder對象,比AtomicLong性能更好(減少樂觀鎖的重試次數(shù))。
?14.【參考】HashM叩在容量不夠進(jìn)行resize時(shí)由于高并發(fā)可能出現(xiàn)死鏈,導(dǎo)致CPU飆升,
在開發(fā)過程中可以使用其它數(shù)據(jù)結(jié)構(gòu)或加鎖來規(guī)避此風(fēng)險(xiǎn)。
?15.【參考】ThreadLocal無法解決共享對象的更新問題,ThreadLocal對象建議使用static
修飾。這個(gè)變量是針對一個(gè)線程內(nèi)所有操作共享的,所以設(shè)置為靜態(tài)變量,所有此類實(shí)例共享
此靜態(tài)變量,也就是說在類第一次被使用時(shí)裝載,只分配一塊存儲(chǔ)空間,所有此類的對象(只要
是這個(gè)線程內(nèi)定義的)都可以操控這個(gè)變量。
?控制語句
?1.【強(qiáng)制】在一個(gè)switch塊內(nèi),每個(gè)case要么通過break/return等來終止,要么注釋說明
程序?qū)⒗^續(xù)執(zhí)行到哪一個(gè)case為止;在一個(gè)switch塊內(nèi),都必須包含一個(gè)default語句并且
放在最后,即使它什么代碼也沒有。
?2.【強(qiáng)制】在if/else/for/while/d。語句中必須使用大括號(hào)。即使只有一行代碼,避免采用單
行的編碼方式:if(condition)statements;
?3.【推薦】表達(dá)異常的分支時(shí),少用if-else方式,這種方式可以改寫成:
?說明:如果非得使用if()...elseif()...else…方式表達(dá)邏輯,【強(qiáng)制】避免后續(xù)代碼維護(hù)困難,
請勿超過3層。
?正例:超過3層的if-else的邏輯判斷代碼可以使用衛(wèi)語句、策略模式、狀態(tài)模式等來實(shí)現(xiàn),
其中衛(wèi)語句示例如下:
?4.【推薦】除常用方法(如getXxx/isXxx)等外,不要在條件判斷中執(zhí)行其它復(fù)雜的語句,將
復(fù)雜邏輯判斷的結(jié)果賦值給一個(gè)有意義的布爾變量名,以提高可讀性。
?說明:很多計(jì)語句內(nèi)的邏輯相當(dāng)復(fù)雜,閱讀者需要分析條件表達(dá)式的最終結(jié)果,才能明確
什么樣的條件執(zhí)行什么樣的語句,那么,如果閱讀者分析邏輯表達(dá)式錯(cuò)誤呢?
?正例:
?5.【推薦】循環(huán)體中的語句要考量性能,以下操作盡量移至循環(huán)體外處理,如定義對象、變量、
獲取數(shù)據(jù)庫連接,進(jìn)行不必要的try-catch操作(這個(gè)try-catch是否可以移至循環(huán)體外)。
?6.【推薦】接口入?yún)⒈Wo(hù),這種場景常見的是用于做批量操作的接口。
?7.【參考】下列情形,需要進(jìn)行參數(shù)校驗(yàn):
?1)調(diào)用頻次低的方法。
?2)執(zhí)行時(shí)間開銷很大的方法。此情形中,參數(shù)校驗(yàn)時(shí)間幾乎可以忽略不計(jì),但如果因?yàn)?/p>
參數(shù)錯(cuò)誤導(dǎo)致中間執(zhí)行回退,或者錯(cuò)誤,那得不償失。
?3)需要極高穩(wěn)定性和可用性的方法。
?4)對勺屣供的開放接口,不管是RPC/API/HTTP接口。
?5)敏感權(quán)限入口。
?8.【參考】下列情形,不需要進(jìn)行參數(shù)校驗(yàn):
?1)極有可能被循環(huán)調(diào)用的方法。但在方法說明里必須注明外部參數(shù)檢杳要求。
?2)底層調(diào)用頻度比較高的方法。畢竟是像純凈水過濾的最后一道,參數(shù)錯(cuò)誤不太可能到
底層才會(huì)暴露問題。一般DAO層與Service層都在同一個(gè)應(yīng)用中,部署在同一臺(tái)服務(wù)器中,
所以DAO的參數(shù)校驗(yàn),可以省略。
?3)被聲明成private只會(huì)被自己代碼所調(diào)用的方法,如果能夠確定調(diào)用方法的代碼傳入?yún)?/p>
數(shù)已經(jīng)做過檢查或者肯定不會(huì)有問題,此時(shí)可以不校驗(yàn)參數(shù)。
?注釋規(guī)約
?1.【強(qiáng)制】類、類屬性、類方法的注釋必須使用Javadoc規(guī)范,使用/**內(nèi)容*/格式,不得使
用〃XXX方式。
?說明:在IDE編輯窗口中,Javadoc方式會(huì)提示相關(guān)注釋,生成Javadoc可以正確輸出相
應(yīng)注釋;在IDE中,工程調(diào)用方法時(shí),不進(jìn)入方法即可懸浮提示方法、參數(shù)、返回值的意
義,提高閱讀效率。
?2.【強(qiáng)制】所有的抽象方法(包括接口中的方法)必須要用Javadoc注釋、除了返回值、參數(shù)、
異常說明外,還必須指出該方法做什么事情,實(shí)現(xiàn)什么功能。
?說明:對子類的實(shí)現(xiàn)要求,或者調(diào)用注意事項(xiàng),請一并說明。
?3.【強(qiáng)制】所有的類都必須添加創(chuàng)建者和創(chuàng)建日期。
?4.【強(qiáng)制】方法內(nèi)部單行注釋,在被注釋語句上方另起一行,使用〃注釋。方法內(nèi)部多行注釋
使用/**/注釋,注意與代碼對齊。
?5.【強(qiáng)制】所有的枚舉類型字段必須要有注釋,說明每個(gè)數(shù)據(jù)項(xiàng)的用途。
?6.【推薦】與其“半吊子”英文來注釋,不如用中文注釋把問題說清楚。專有名詞與關(guān)鍵字保
持英文原文即可.
?反例:"TCP連接超時(shí)"解釋成"傳輸控制協(xié)議連接超時(shí)",理解反而費(fèi)腦筋。
?7.【推薦】代碼修改的同時(shí),注釋也要進(jìn)行相應(yīng)的修改,尤其是參數(shù)、返回值、異常、核心邏
輯等的修改。
?說明:代碼與注釋更新不同步,就像路網(wǎng)與導(dǎo)航軟件更新不同步一樣,如果導(dǎo)航軟件嚴(yán)重
滯后,就失去了導(dǎo)航的意義。
?8.【參考】謹(jǐn)慎注釋掉代碼。在上方詳細(xì)說明,而不是簡單地注釋掉。如果無用,則刪除。
?說明:代碼被注釋掉有兩種可能性:1)后續(xù)會(huì)恢復(fù)此段代碼邏輯。2)永久不用。前者如
果沒有備注信息,難以知曉注釋動(dòng)機(jī)。后者建議直接刪掉(代碼倉庫保存了歷史代碼)。
?9.【參考】對于注釋的要求:第一、能夠準(zhǔn)確反應(yīng)設(shè)計(jì)思想和代碼邏輯;第二、能夠描述業(yè)務(wù)
含義,使別的程序員能夠迅速了解到代碼背后的信息。完全沒有注釋的大段代碼對于閱讀者形
同天書,注釋是給自己看的,即使隔很長時(shí)間,也能清晰理解當(dāng)時(shí)的思路;注釋也是給繼任者
看的,使其能夠快速接替自己的工作。
?10.【參考】好的命名、代碼結(jié)構(gòu)是自解釋的,注釋力求精簡準(zhǔn)確、表達(dá)到位。避免出現(xiàn)注釋
的一個(gè)極端:過多過濫的注釋代碼的邏輯一旦修改,修改注釋是相當(dāng)大的負(fù)擔(dān)。方法名put,
加上兩個(gè)有意義的變量名elephant和fridge,已經(jīng)說明了這是在干什么,語義清晰的代碼不
需要額外的注釋。
?M.【參考】特殊注釋標(biāo)記,請注明標(biāo)記人與標(biāo)記時(shí)間。注意及時(shí)處理這些標(biāo)記,通過標(biāo)記掃
描,經(jīng)常清理此類標(biāo)記。線上故障有時(shí)候就是來源于這些標(biāo)記處的代碼。
?1)待辦事宜(TODO):(標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間])表示需要實(shí)現(xiàn),但目前
還未實(shí)現(xiàn)的功能。這實(shí)際上是一個(gè)Javadoc的標(biāo)簽,目前的Javadoc還沒有實(shí)現(xiàn),但已經(jīng)
被廣泛使用。只能應(yīng)用于類,接口和方法(因?yàn)樗且粋€(gè)Javadoc標(biāo)簽)。
?2)錯(cuò)誤,不能工作(FIXME):(標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間])在注釋中用
FIXME標(biāo)記某代碼是錯(cuò)誤的,而且不能工作,需要及時(shí)糾正的情況。
■其它
?1.【強(qiáng)制】在使用正則表達(dá)式時(shí),利用好其預(yù)編譯功能,可以有效加快正則匹配速度。
?說明:不要在方法體內(nèi)定義:Patternpattern=Ppile(規(guī)則);
?2.【強(qiáng)制】velocity調(diào)用POJO類的屬性時(shí),建議直接使用屬性名取值即可,模板引擎會(huì)自動(dòng)
按規(guī)范調(diào)用POJO的getXxx(),如果是boolean基本數(shù)據(jù)類型變量(boolean命名不需要加
is前綴),會(huì)自動(dòng)調(diào)用isXxx()方法。
?說明:注意如果是Boolean包裝類對象,優(yōu)先調(diào)用getXxx()的方法。
?3.【強(qiáng)制】后臺(tái)輸送給頁面的變量必須加$!的「}——中間的感嘆號(hào)。
?說明:如果var=null或者不存在,那么${var}會(huì)直接顯示在頁面上。
?4.【強(qiáng)制】注意Math.randomO這個(gè)方法返回是double類型,注意取值的范圍0<x<l(能
夠取到零值,注意除零異常),如果想獲取整數(shù)類型的隨機(jī)數(shù),不要將x放大10的若干倍然
后取整,直接使用Random對象的nextlnt或者nextLong方法。
?5.【強(qiáng)制】獲取當(dāng)前毫秒數(shù)System.currentTimeMillis();而不是newDate().getTime();
?說明:如果想獲取更加精確的納秒級時(shí)間值,使用System.nanoTimeO的方式。在JDK8
中,針對統(tǒng)計(jì)時(shí)間等場景,推薦使用Instant類。
?6.【推薦】不要在視圖模板中加入任何復(fù)雜的邏輯。
?說明:根據(jù)MVC理論,視圖的職責(zé)是展示,不要搶模型和控制器的活。
?7.【推薦】任何數(shù)據(jù)結(jié)構(gòu)的構(gòu)造或初始化,都應(yīng)指定大小,避免數(shù)據(jù)結(jié)構(gòu)無限增長吃光內(nèi)存。
?8.【推薦】及時(shí)清理不再使用的代碼段或配置信息。
?說明:對于垃圾代碼或過時(shí)配置,堅(jiān)決清理干凈,避免程序過度臃腫,代碼冗余。
?正例:對于暫時(shí)被注釋掉,后續(xù)可能恢復(fù)使用的代碼片斷,在注釋代碼上方,統(tǒng)一規(guī)定使
用三個(gè)斜杠(〃/)來說明注釋掉代碼的理由
?異常日志
?異常處理
?1.【強(qiáng)制】Java類庫中定義的一類RuntimeException可以通過預(yù)先檢查進(jìn)行規(guī)避,而不應(yīng)該通
過catch來處理,比如:IndexOutOfBoundsException,NullPointerException等等。
?說明:無法通過預(yù)檢查的異常除外,如在解析一個(gè)外部傳來的字符串形式數(shù)字時(shí),通過
catchNumberFormatException來實(shí)現(xiàn)。
?正例:if(obj!=null){...}
?反例:try{obj.method()}catch(NullPointerExceptione){...}
?2.【強(qiáng)制】異常不要用來做流程控制,條件控制,因?yàn)楫惓5奶幚硇时葪l件分支低。
?3.【強(qiáng)制】對大段代碼進(jìn)行try-catch,這是不負(fù)責(zé)任的表現(xiàn)。catch時(shí)請分清穩(wěn)定代碼和非穩(wěn)定
代碼,穩(wěn)定代碼指的是無論如何不會(huì)出錯(cuò)的代碼。對于非穩(wěn)定代碼的catch盡可能進(jìn)行區(qū)分異常類
型,再做對應(yīng)的異常處理。
?4.【強(qiáng)制】捕獲異常是為了處理它,不要捕獲了卻什么都不處理而拋棄之,如果不想處理它,請將
該異常拋給它的調(diào)用者。最外層的業(yè)務(wù)使用者,必須處理異常,將其轉(zhuǎn)化為用戶可以理解的內(nèi)容。
?5.【強(qiáng)制】有try塊放到了事務(wù)代碼中,catch異常后,如果需要回滾事務(wù),一定要注意手動(dòng)回滾
事務(wù)。
?6.【強(qiáng)制】finally塊必須對資源對象、流對象進(jìn)行關(guān)閉,有異常也要做try-catch。
?說明:如果JDK7及以上,可以使用try-with-resources方式。
?7.【強(qiáng)制】不能在finally塊中使用return,finally塊中的return返回后方法結(jié)束執(zhí)行,不會(huì)再
執(zhí)行try塊中的return語句。
?8.【強(qiáng)制】捕獲異常與拋異常,必須是完全匹配,或者捕獲異常是拋異常的父類。
?說明:如果預(yù)期對方拋的是繡球,實(shí)際接到的是鉛球,就會(huì)產(chǎn)生意外情況。
?9.【推薦】方法的返回值可以為null,不強(qiáng)制返回空集合,或者空對象等,必須添加注釋充分說明
什么情況下會(huì)返回null值。調(diào)用方需要進(jìn)行null判斷防止NPE問題。
?說明:本手冊明確防止NPE是調(diào)用者的責(zé)任。即使被調(diào)用方法返回空集合或者空對象,對調(diào)用
者來說,也并非高枕無憂,必須考慮到遠(yuǎn)程調(diào)用失敗、序列化失敗、運(yùn)行時(shí)異常等場景返回
null的情況。
?10.【推薦】防止NPE,是程序員的基本修養(yǎng),注意NPE產(chǎn)生的場景:
?1)返回類型為基本數(shù)據(jù)類型,return包裝數(shù)據(jù)類型的對象時(shí),自動(dòng)拆箱有可能產(chǎn)生NPE。
?反例:publicintf(){returnInteger對象},如果為null,自動(dòng)解箱拋NPE。
?2)數(shù)據(jù)庫的查詢結(jié)果可能為null.
?3)集合里的元素即使isNotEmpty,取出的數(shù)據(jù)元素也可能為null。
?4)遠(yuǎn)程調(diào)用返回對象時(shí),一律要求進(jìn)行空指針判斷,防止NPE。
?5)對于Session中獲取的數(shù)據(jù),建議NPE檢查,避免空指針。
?6)級聯(lián)調(diào)用obj.getA().getB().getC();一連串調(diào)用,易產(chǎn)生NPE。
?正例:使用JDK8的Optional類來防止NPE問題。
?11.【推薦】定義時(shí)區(qū)分unchecked/checked異常,避免直接拋出newRuntimeException(),
更不允許拋出Exception或者Throwable,應(yīng)使用有業(yè)務(wù)含義的自定義異常。推薦業(yè)界已定義過
的自定義異常,如:DAOException/ServiceException等。
?12.【參考】在代碼中使用“拋異常"還是"返回錯(cuò)誤碼",對于公司外的http/api開放接口必須
使用"錯(cuò)誤碼";而應(yīng)用內(nèi)部推薦異常拋出;跨應(yīng)用間RPC調(diào)用優(yōu)先考慮使用Result方式,封裝
isSuccess。方法、"錯(cuò)誤碼"、"錯(cuò)誤簡短信息"。說明:關(guān)于RPC方法返回方式使用Result方
式的理由:
?1)使用拋異常返回方式,調(diào)用方如果沒有捕獲到就會(huì)產(chǎn)生運(yùn)行時(shí)錯(cuò)誤。
?2)如果不加棧信息,只是new自定義異常,加入自己的理解的errormessage,對于調(diào)用端
解決問題的幫助不會(huì)太多。如果加了棧信息,在頻繁調(diào)用出錯(cuò)的情況下,數(shù)據(jù)序列化和傳輸?shù)?/p>
性能損耗也是問題。
?13.【參考】避免出現(xiàn)重復(fù)的代碼(Don'tRepeatYourself),即DRY原則。
?說明:隨意復(fù)制和粘貼代碼,必然會(huì)導(dǎo)致代碼的重復(fù),在以后需要修改時(shí),需要修改所有的副
本,容易遺漏。必要時(shí)抽取共性方法,或者抽象公共類,甚至是組件化。
?正例:一個(gè)類中有多個(gè)public方法,都需要進(jìn)行數(shù)行相同的參數(shù)校驗(yàn)操作,這個(gè)時(shí)候請抽?。?/p>
privatebooleancheckParam(DTOdto){...}
?日志規(guī)約
?1.【強(qiáng)制】應(yīng)用中不可直接使月日志系統(tǒng)(Log4j、Logback)中的API,而應(yīng)依賴使用日志
框架SLF4J中的API,使用門面模式的日志框架,有利于維護(hù)和各個(gè)類的日志處理方式統(tǒng)一。
importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;privatestaticfinalLogger
logger=LoggerFactory.getLogger(Abc.class);
?2.【強(qiáng)制】日志文件推薦至少保存15天,因?yàn)橛行┊惓>邆湟?周"為頻次發(fā)生的特點(diǎn)。
appName_logType_logName.log。logType:日志類型,推薦分類有
stats/desc/monitor/visit等;logName:日志描述。這種命名的好處:通過文件名就可知道
日志文件屬于什么應(yīng)用,什么類型,什么目的,也有利于歸類查找。
?正例:mppserver應(yīng)用中單獨(dú)監(jiān)控時(shí)區(qū)轉(zhuǎn)換異常,如:
mppserver_monitor_timeZoneConvert.log
?說明:推薦對日志進(jìn)行分類,如將錯(cuò)誤日志和業(yè)務(wù)日志分開存放,便于開發(fā)人員查看,也
便于通過日志對系統(tǒng)進(jìn)行及時(shí)觸。
?4.【強(qiáng)制】對trace/debug/info級別的日志輸出,必須使用條件輸出形式或者使用占位符的
方式。
?說明:logger.debugCProcessingtradewithid:"+id+'andsymbol:"+symbol);
如果日志級別是warn,上述日志不會(huì)打印,但是會(huì)執(zhí)行字符串拼接操作,如果symbol是
對象,會(huì)執(zhí)行toStringO方法,浪費(fèi)了系統(tǒng)資源,執(zhí)行了上述操作,最終日志卻沒有打印。
?正例:(條件)
if(logger.isDebugEnabledO){logger.debug("Processingtradewithid:"+id+"
andsymbol:"+symbol);}
?正例:(占位符)
logger.debug("Processingtradewithid:{}andsymbol:{}"id,symbol);
?5.【強(qiáng)制】避免重復(fù)打印日志,浪費(fèi)磁盤空間,務(wù)必在Iog4j.xml中設(shè)置additivity:false。
?正例:<loggername="com.taobao.dubbo.config"additivity="false">
?6.【強(qiáng)制】異常信息應(yīng)該包括兩類信息:案發(fā)現(xiàn)場信息和異常堆棧信息。如果不處理,那么通
過關(guān)鍵字throws往上拋出。
?正例:logger.error(各類參數(shù)或者對象toString++e.getMessageO,e);
?7.【推薦】謹(jǐn)慎地記錄日志。生產(chǎn)環(huán)境禁止輸出debug日志;有選擇地輸出info日志;如果
使用warn來記錄剛上線時(shí)的業(yè)務(wù)行為信息,一定要注意日志輸出量的問題,避免把服務(wù)器磁
盤撐爆,并記得及時(shí)刪除這些觀察日志。
?說明:大量地輸出無效日志,不利于系統(tǒng)性能提升,也不利于快速定位錯(cuò)誤點(diǎn)。記錄日志
時(shí)請
?思考:這些日志真的有人看嗎?看到這條日志你能做什么?能不能給問題排查帶來好處?
?8.【參考】可以使用warn日志級別來記錄用戶輸入?yún)?shù)錯(cuò)誤的情況,避免用戶投訴時(shí),無所
適從。注意日志輸出的級別,error級別只記錄系統(tǒng)邏輯出錯(cuò)、異常等重要的錯(cuò)誤信息。如非
必要,請不要在此場景打出error級別。
?單元測試
?1.【強(qiáng)制】好的單元測試必須遵守AIR原則。
?說明:單元測試在線上運(yùn)行時(shí),感覺像空氣(AIR)一樣并不存在,但在測試質(zhì)量的保障上,
卻是非常關(guān)鍵的。好的單元測試宏觀上來說,具有自動(dòng)化、獨(dú)立性、可重復(fù)執(zhí)行的特點(diǎn)。
?A:Automatic(自動(dòng)化)
?I:Independent(獨(dú)立性)
?R:Repeatable(可重復(fù))
?2.【強(qiáng)制】單元測試應(yīng)該是全自動(dòng)執(zhí)行的,并且非交互式的。測試框架通常是定期執(zhí)行的,執(zhí)行過
程必須完全自動(dòng)化才有意義。輸出結(jié)果需要人工檢查的測試不是一個(gè)好的單元測試。單元測試中不
準(zhǔn)使用System.out來進(jìn)行人肉驗(yàn)證,必須使用assert來驗(yàn)證。
?3.【強(qiáng)制】保持單元測試的獨(dú)立性。為了保證單元測試穩(wěn)定可靠且便于維護(hù),單元測試用例之間決
不能互相調(diào)用,也不能依賴執(zhí)行的先后次序。
?反例:method2需要依賴me:hodl的執(zhí)行,將執(zhí)行結(jié)果做為m
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年滬教新版七年級生物上冊階段測試試卷含答案
- 2024-2025學(xué)年江山市數(shù)學(xué)三上期末綜合測試模擬試題含解析
- 健康教育的新篇章跨學(xué)科合作在學(xué)校的應(yīng)用
- 2024年電力設(shè)施安裝勞務(wù)作業(yè)分包書
- 2024年專業(yè)會(huì)議資料定制與印制合同3篇
- 以數(shù)據(jù)驅(qū)動(dòng)的家庭健身計(jì)劃調(diào)整與優(yōu)化
- 辦公環(huán)境中如何幫助員工建立自信心
- 2025中國鐵塔集團(tuán)河南分公司招聘25人高頻重點(diǎn)提升(共500題)附帶答案詳解
- 2025中國西電集團(tuán)(中國西電)招聘22人高頻重點(diǎn)提升(共500題)附帶答案詳解
- 2025中國石化高橋石化分公司畢業(yè)生招聘30人高頻重點(diǎn)提升(共500題)附帶答案詳解
- 2024年遼寧石化職業(yè)技術(shù)學(xué)院單招職業(yè)適應(yīng)性測試題庫必考題
- 理論力學(xué)(山東科技大學(xué)) 知到智慧樹網(wǎng)課答案
- 北師大版九下《直角三角形邊角關(guān)系》
- 中國音樂史與名作賞析智慧樹知到期末考試答案章節(jié)答案2024年山東師范大學(xué)
- 切斷機(jī)液壓系統(tǒng)畢業(yè)設(shè)計(jì)論文
- MOOC 人工智能導(dǎo)論-浙江工業(yè)大學(xué) 中國大學(xué)慕課答案
- 三位數(shù)除以兩位數(shù)-計(jì)算題-100題-豎式
- 第1課 《蓼莪》 公開課一等獎(jiǎng)創(chuàng)新教案(表格式)《大學(xué)語文(第四版)》(高職版)
- 項(xiàng)目式教學(xué)設(shè)計(jì)與實(shí)施
- 數(shù)字經(jīng)濟(jì)職業(yè)生涯規(guī)劃
- 煤礦安全生產(chǎn)管理人員逢查必考題庫(500題)
評論
0/150
提交評論