阿里JAVA編碼規(guī)范手冊_第1頁
阿里JAVA編碼規(guī)范手冊_第2頁
阿里JAVA編碼規(guī)范手冊_第3頁
阿里JAVA編碼規(guī)范手冊_第4頁
阿里JAVA編碼規(guī)范手冊_第5頁
已閱讀5頁,還剩32頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、 目錄前言.1一、編程規(guī)約.2(一) 命名規(guī)約 .2(二) 常量定義 .4(三) 格式規(guī)約 .5(四) OOP規(guī)約 .7(五) 集合處理 .11(六) 并發(fā)處理 .13(七) 控制語句 .16(八) 注釋規(guī)約 .17(九) 其它.18二、異常日志.20(一) 異常處理 .20(二) 日志規(guī)約 .21三、MySQL規(guī)約.23(一) 建表規(guī)約 .23(二) 索引規(guī)約 .25(三) SQL規(guī)約 .27(四) ORM規(guī)約 .28四、工程規(guī)約.29(一) 應(yīng)用分層 .29(二) 二方庫規(guī)約.30(三) 服務(wù)器規(guī)約.32五、安全規(guī)約.33附 1:版本歷史 .34附 2:本規(guī)約專有名詞.34附 3:法律聲明

2、 .34(注:全文瀏覽時請使用 PDF左側(cè)導(dǎo)航欄) 阿里巴巴 Java開發(fā)手冊前言阿里巴巴 Java開發(fā)手冊是阿里巴巴集團(tuán)技術(shù)團(tuán)隊(duì)的集體經(jīng)驗(yàn)總結(jié),經(jīng)歷了多次大規(guī)模一線實(shí)戰(zhàn)的檢驗(yàn)及不斷的完善,反饋給廣大開發(fā)者。現(xiàn)代軟件行業(yè)的高速發(fā)展對于開發(fā)者的綜合素質(zhì)要求越來越高,因?yàn)椴粌H是編程知識點(diǎn),其它維度的知識點(diǎn)也會影響到軟件的最終交付質(zhì)量。比如:數(shù)據(jù)庫的表結(jié)構(gòu)和索引設(shè)計(jì)缺陷可能帶來軟件上的架構(gòu)缺陷或性能風(fēng)險;工程結(jié)構(gòu)混亂導(dǎo)致維護(hù)困難;沒有鑒權(quán)的漏洞代碼被黑客攻擊等等。所以本手冊以 Java開發(fā)者為中心視角,劃分為編程規(guī)約、異常日志規(guī)約、MySQL規(guī)約、工程規(guī)約、安全規(guī)約五大塊,再根據(jù)內(nèi)容特征,細(xì)分成若干

3、二級子目錄。根據(jù)約束力強(qiáng)弱及故障敏感性,規(guī)約依次分為強(qiáng)制、推薦、參考三大類。對于規(guī)約里的內(nèi)容,“說明”對內(nèi)容做了引申和解釋;“正例”提倡什么樣的編碼和實(shí)現(xiàn)方式;“反例”說明需要提防的雷區(qū),以及真實(shí)的錯誤案例。本手冊的愿景是碼出質(zhì)量、碼出高效。代碼的字里行間流淌的是軟件生命中的血液,質(zhì)量的提升是盡可能少踩坑,杜絕踩重復(fù)的坑,切實(shí)提升質(zhì)量意識。另外,現(xiàn)代軟件架構(gòu)都需要協(xié)同開發(fā)完成,高效考慮的是降低協(xié)同成本,所謂無規(guī)矩不成方圓,無規(guī)范不能協(xié)作。眾所周知,制訂交通法規(guī)表面上是要限制行車權(quán),實(shí)際上是保障公眾的人身安全。試想如果沒有限速,沒有紅綠燈,沒有規(guī)定靠右行駛,誰還敢上路行駛。對軟件來說,適當(dāng)?shù)囊?guī)范

4、和標(biāo)準(zhǔn)絕不是消滅代碼內(nèi)容的創(chuàng)造性、優(yōu)雅性,而是限制過度個性化,以一種普遍認(rèn)可的統(tǒng)一方式一起做事,提升協(xié)作效率。阿里巴巴 Java開發(fā)手冊,開放包容地認(rèn)真總結(jié)社區(qū)、博客、論壇的反饋,及時修正,保持與時俱進(jìn)。請關(guān)注手冊末頁的“阿里技術(shù)”和“云棲社區(qū)”公眾號獲取最新版。禁止用于商業(yè)用途,違者必究1 / 37 阿里巴巴 Java開發(fā)手冊Java開發(fā)手冊版本號制定團(tuán)隊(duì)更新日期備注1.1.0阿里巴巴集團(tuán)技術(shù)團(tuán)隊(duì)2017.2.27增加前言和專有名詞說明,修正部分描述。一、編程規(guī)約(一)命名規(guī)約1.【強(qiáng)制】 代碼中的命名均不能以下劃線或美元符號開始,也不能以下劃線或美元符號結(jié)束。反例: _name / _na

5、me / $Object / name_ / name$ / Object$2.【強(qiáng)制】 代碼中的命名嚴(yán)禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。說明:正確的英文拼寫和語法可以讓閱讀者易于理解,避免歧義。注意,即使純拼音命名方式也要避免采用。反例: DaZhePromotion 打折 / getPingfenByName() 評分 / int 某變量 = 3正例: alibaba / taobao / youku / hangzhou 等國際通用的名稱,可視同英文。3.【強(qiáng)制】類名使用 UpperCamelCase風(fēng)格,必須遵從駝峰形式,但以下情形例外:(領(lǐng)域模型的相關(guān)命名)DO

6、 / BO / DTO / VO等。正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion4.【強(qiáng)制】方法名、參數(shù)名、成員變量、局部變量都統(tǒng)一使用 lowerCamelCase風(fēng)格,必須遵從駝峰形式。正例: localValue / getHttpMessage() / inputUserId5.【強(qiáng)制】常量命名全部大寫,單詞間用下劃線隔開,力求語義表達(dá)完整清楚,不要嫌名字長。正例: MAX_STOCK_C

7、OUNT反例: MAX_COUNT6.【強(qiáng)制】抽象類命名使用 Abstract或 Base開頭;異常類命名使用 Exception結(jié)尾;測試類命名以它要測試的類的名稱開始,以 Test結(jié)尾。7.【強(qiáng)制】中括號是數(shù)組類型的一部分,數(shù)組定義如下:String args;反例:使用 String args的方式來定義。禁止用于商業(yè)用途,違者必究2 / 37 阿里巴巴 Java開發(fā)手冊8.【強(qiáng)制】POJO類中布爾類型的變量,都不要加 is,否則部分框架解析會引起序列化錯誤。反例:定義為基本數(shù)據(jù)類型 Boolean isSuccess;的屬性,它的方法也是 isSuccess(),RPC框架在反向解析的

8、時候,“以為”對應(yīng)的屬性名稱是 success,導(dǎo)致屬性獲取不到,進(jìn)而拋出異常。9.【強(qiáng)制】包名統(tǒng)一使用小寫,點(diǎn)分隔符之間有且僅有一個自然語義的英語單詞。包名統(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.【推薦】如果使用到了設(shè)計(jì)模式,

9、建議在類名中體現(xiàn)出具體模式。說明:將設(shè)計(jì)模式體現(xiàn)在名字中,有利于閱讀者快速理解架構(gòu)設(shè)計(jì)思想。正例:public class OrderFactory;public class LoginProxy;public class ResourceObserver;12.【推薦】接口類中的方法和屬性不要加任何修飾符號(public 也不要加),保持代碼的簡潔性,并加上有效的 Javadoc注釋。盡量不要在接口里定義變量,如果一定要定義變量,肯定是與接口方法相關(guān),并且是整個應(yīng)用的基礎(chǔ)常量。正例:接口方法簽名:void f();接口基礎(chǔ)常量表示:String COMPANY = "alibaba

10、"反例:接口方法定義:public abstract void f();說明:JDK8中接口允許有默認(rèn)實(shí)現(xiàn),那么這個 default方法,是對所有實(shí)現(xiàn)類都有價值的默認(rèn)實(shí)現(xiàn)。13.接口和實(shí)現(xiàn)類的命名有兩套規(guī)則:1)【強(qiáng)制】對于 Service和 DAO類,基于 SOA的理念,暴露出來的服務(wù)一定是接口,內(nèi)部的實(shí)現(xiàn)類用 Impl的后綴與接口區(qū)別。正例:CacheServiceImpl實(shí)現(xiàn) CacheService接口。2)【推薦】如果是形容能力的接口名稱,取對應(yīng)的形容詞做接口名(通常是able的形式)。正例:AbstractTranslator實(shí)現(xiàn) Translatable。14.【參考】

11、枚舉類名建議帶上 Enum后綴,枚舉成員名稱需要全大寫,單詞間用下劃線隔開。說明:枚舉其實(shí)就是特殊的常量類,且構(gòu)造方法被默認(rèn)強(qiáng)制是私有。正例:枚舉名字:DealStatusEnum,成員名稱:SUCCESS / UNKOWN_REASON。禁止用于商業(yè)用途,違者必究3 / 37 阿里巴巴 Java開發(fā)手冊15.【參考】各層命名規(guī)約:A) Service/DAO層方法命名規(guī)約1) 獲取單個對象的方法用 get做前綴。2) 獲取多個對象的方法用 list做前綴。3) 獲取統(tǒng)計(jì)值的方法用 count做前綴。4) 插入的方法用 save(推薦)或 insert做前綴。5) 刪除的方法用 remove(

12、推薦)或 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)制】不允許出現(xiàn)任何魔法值(即未經(jīng)定義的常量)直接出現(xiàn)在代碼中。反例: String key = "Id#taobao_"+tradeId;cache.put(key, value);2.【強(qiáng)制】long或者 Long初始賦值時,

13、必須使用大寫的 L,不能是小寫的 l,小寫容易跟數(shù)字1混淆,造成誤解。說明:Long a = 2l; 寫的是數(shù)字的 21,還是 Long型的 2?3.【推薦】不要使用一個常量類維護(hù)所有常量,應(yīng)該按常量功能進(jìn)行歸類,分開維護(hù)。如:緩存相關(guān)的常量放在類:CacheConsts下;系統(tǒng)配置相關(guān)的常量放在類:ConfigConsts下。說明:大而全的常量類,非得使用查找功能才能定位到修改的常量,不利于理解和維護(hù)。4.【推薦】常量的復(fù)用層次有五層:跨應(yīng)用共享常量、應(yīng)用內(nèi)共享常量、子工程內(nèi)共享常量、包內(nèi)共享常量、類內(nèi)共享常量。1) 跨應(yīng)用共享常量:放置在二方庫中,通常是 client.jar中的 cons

14、tant目錄下。2) 應(yīng)用內(nèi)共享常量:放置在一方庫的 modules中的 constant目錄下。反例:易懂變量也要統(tǒng)一定義成應(yīng)用內(nèi)共享常量,兩位攻城師在兩個類中分別定義了表示“是”的變量:類 A中:public static final String YES = "yes"類 B中:public static final String YES = "y"A.YES.equals(B.YES),預(yù)期是 true,但實(shí)際返回為 false,導(dǎo)致產(chǎn)生線上問題。禁止用于商業(yè)用途,違者必究4 / 37 阿里巴巴 Java開發(fā)手冊3) 子工程內(nèi)部共享常量:即在當(dāng)前

15、子工程的 constant目錄下。4) 包內(nèi)共享常量:即在當(dāng)前包下單獨(dú)的 constant目錄下。5) 類內(nèi)共享常量:直接在類內(nèi)部 private static final定義。5.【推薦】如果變量值僅在一個范圍內(nèi)變化用 Enum類。如果還帶有名稱之外的延伸屬性,必須使用 Enum類,下面正例中的數(shù)字就是延伸信息,表示星期幾。正例:public EnumMONDAY(1), TUESDAY(2),WEDNESDAY(3),THURSDAY(4),FRIDAY(5),SATURDAY(6),SUNDAY(7);(三)格式規(guī)約1.【強(qiáng)制】大括號的使用約定。如果是大括號內(nèi)為空,則簡潔地寫成即可,不需

16、要換行;如果是非空代碼塊則:1) 左大括號前不換行。2) 左大括號后換行。3) 右大括號前換行。4) 右大括號后還有 else等代碼則不換行;表示終止右大括號后必須換行。2.【強(qiáng)制】 左括號和后一個字符之間不出現(xiàn)空格;同樣,右括號和前一個字符之間也不出現(xiàn)空格。詳見第 5條下方正例提示。3.【強(qiáng)制】if/for/while/switch/do等保留字與左右括號之間都必須加空格。4.【強(qiáng)制】任何運(yùn)算符左右必須加一個空格。說明:運(yùn)算符包括賦值運(yùn)算符=、邏輯運(yùn)算符&&、加減乘除符號、三目運(yùn)算符等。5.【強(qiáng)制】縮進(jìn)采用 4個空格,禁止使用 tab字符。說明:如果使用 tab縮進(jìn),必須設(shè)置

17、 1個 tab為 4個空格。IDEA設(shè)置 tab為 4個空格時,請勿勾選 Use tab character;而在 eclipse中,必須勾選 insert spaces for tabs。正例: (涉及 1-5點(diǎn))public static void main(String args) / 縮進(jìn) 4個空格String say = "hello"/ 運(yùn)算符的左右必須有一個空格int flag = 0;/ 關(guān)鍵詞 if與括號之間必須有一個空格,括號內(nèi)的 f與左括號,0與右括號不需要空格if (flag = 0) System.out.println(say);/ 左大括號前加

18、空格且不換行;左大括號后換行if (flag = 1) System.out.println("world");/ 右大括號前換行,右大括號后有 else,不用換行禁止用于商業(yè)用途,違者必究5 / 37 阿里巴巴 Java開發(fā)手冊 else System.out.println("ok");/ 在右大括號后直接結(jié)束,則必須換行6.【強(qiáng)制】單行字符數(shù)限制不超過 120 個,超出需要換行,換行時遵循如下原則:1) 第二行相對第一行縮進(jìn) 4 個空格,從第三行開始,不再繼續(xù)縮進(jìn),參考示例。2) 運(yùn)算符與下文一起換行。3) 方法調(diào)用的點(diǎn)符號與下文一起換行。4) 在

19、多個參數(shù)超長,逗號后進(jìn)行換行。5) 在括號前不要換行,見反例。正例:StringBuffer sb = new StringBuffer();/超過 120個字符的情況下,換行縮進(jìn) 4個空格,并且方法前的點(diǎn)符號一起換行sb.append("zi").append("xin").append("huang").append("huang").append("huang");反例:StringBuffer sb = new StringBuffer();/超過 120個字符的情況下,不要在括號前換行

20、sb.append("zi").append("xin").append("huang");/參數(shù)很多的方法調(diào)用可能超過 120個字符,不要在逗號前換行method(args1, args2, args3, ., argsX);7.【強(qiáng)制】方法參數(shù)在定義和傳入時,多個參數(shù)逗號后邊必須加空格。正例:下例中實(shí)參的"a",后邊必須要有一個空格。method("a", "b", "c");8.【強(qiáng)制】IDE的 text file encoding設(shè)置為 UTF-8

21、; IDE中文件的換行符使用 Unix格式,不要使用 windows格式。9.【推薦】沒有必要增加若干空格來使某一行的字符與上一行的相應(yīng)字符對齊。正例:int a = 3;long b = 4L;float c = 5F;StringBuffer sb = new StringBuffer();說明:增加 sb這個變量,如果需要對齊,則給 a、b、c都要增加幾個空格,在變量比較多的情況下,是一種累贅的事情。禁止用于商業(yè)用途,違者必究6 / 37 阿里巴巴 Java開發(fā)手冊10.【推薦】方法體內(nèi)的執(zhí)行語句組、變量的定義語句組、不同的業(yè)務(wù)邏輯之間或者不同的語義之間插入一個空行。相同業(yè)務(wù)邏輯和語義之

22、間不需要插入空行。說明:沒有必要插入多行空格進(jìn)行隔開。(四)OOP規(guī)約1.【強(qiáng)制】避免通過一個類的對象引用訪問此類的靜態(tài)變量或靜態(tài)方法,無謂增加編譯器解析成本,直接用類名來訪問即可。2.【強(qiáng)制】所有的覆寫方法,必須加Override注解。反例:getObject()與 get0bject()的問題。一個是字母的 O,一個是數(shù)字的 0,加Override可以準(zhǔn)確判斷是否覆蓋成功。另外,如果在抽象類中對方法簽名進(jìn)行修改,其實(shí)現(xiàn)類會馬上編譯報錯。3.【強(qiáng)制】相同參數(shù)類型,相同業(yè)務(wù)含義,才可以使用 Java的可變參數(shù),避免使用 Object。說明:可變參數(shù)必須放置在參數(shù)列表的最后。(提倡同學(xué)們盡量不用

23、可變參數(shù)編程)正例:public User getUsers(String type, Integer. ids)4.【強(qiáng)制】外部正在調(diào)用或者二方庫依賴的接口,不允許修改方法簽名,避免對接口調(diào)用方產(chǎn)生影響。接口過時必須加Deprecated注解,并清晰地說明采用的新接口或者新服務(wù)是什么。5.【強(qiáng)制】不能使用過時的類或方法。說明:.URLDecoder 中的方法 decode(StringencodeStr) 這個方法已經(jīng)過時,應(yīng)該使用雙參數(shù) decode(String source, String encode)。接口提供方既然明確是過時接口,那么有義務(wù)同時提供新的接口;作為調(diào)用方來說,有義務(wù)

24、去考證過時方法的新實(shí)現(xiàn)是什么。6.【強(qiáng)制】Object的 equals方法容易拋空指針異常,應(yīng)使用常量或確定有值的對象來調(diào)用equals。正例: "test".equals(object);反例: object.equals("test");說明:推薦使用 java.util.Objects#equals (JDK7引入的工具類)7.【強(qiáng)制】所有的相同類型的包裝類對象之間值的比較,全部使用 equals方法比較。說明:對于 Integer var = ?在-128至 127之間的賦值,Integer對象是在IntegerCache.cache產(chǎn)生,會復(fù)用

25、已有對象,這個區(qū)間內(nèi)的 Integer值可以直接使用=進(jìn)行判斷,但是這個區(qū)間之外的所有數(shù)據(jù),都會在堆上產(chǎn)生,并不會復(fù)用已有對象,這是一個大坑,推薦使用 equals方法進(jìn)行判斷。禁止用于商業(yè)用途,違者必究7 / 37 阿里巴巴 Java開發(fā)手冊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類屬性沒有初值是提醒使用者在需要使用時,必須自己顯式地進(jìn)行賦值,任何NPE問題,或者入庫檢查,都由使用者來保證。正例:數(shù)據(jù)庫的查

26、詢結(jié)果可能是 null,因?yàn)樽詣硬鹣?,用基本?shù)據(jù)類型接收有 NPE風(fēng)險。反例:比如顯示成交總額漲跌情況,即正負(fù) x%,x為基本數(shù)據(jù)類型,調(diào)用的 RPC服務(wù),調(diào)用不成功時,返回的是默認(rèn)值,頁面顯示:0%,這是不合理的,應(yīng)該顯示成中劃線-。所以包裝數(shù)據(jù)類型的 null值,能夠表示額外的信息,如:遠(yuǎn)程調(diào)用失敗,異常退出。9.【強(qiáng)制】定義 DO/DTO/VO等 POJO類時,不要設(shè)定任何屬性默認(rèn)值。反例:POJO類的 gmtCreate默認(rèn)值為 new Date();但是這個屬性在數(shù)據(jù)提取時并沒有置入具體值,在更新其它字段時又附帶更新了此字段,導(dǎo)致創(chuàng)建時間被修改成當(dāng)前時間。10.【強(qiáng)制】序列化類新增屬

27、性時,請不要修改 serialVersionUID字段,避免反序列失??;如果完全不兼容升級,避免反序列化混亂,那么請修改 serialVersionUID值。說明:注意 serialVersionUID不一致會拋出序列化運(yùn)行時異常。11.【強(qiáng)制】構(gòu)造方法里面禁止加入任何業(yè)務(wù)邏輯,如果有初始化邏輯,請放在 init方法中。12.【強(qiáng)制】POJO類必須寫 toString方法。使用 IDE的中工具:source>generate toString時,如果繼承了另一個 POJO類,注意在前面加一下 super.toString。說明:在方法執(zhí)行拋出異常時,可以直接調(diào)用 POJO的 toStri

28、ng()方法打印其屬性值,便于排查問題。13.【推薦】使用索引訪問用 String的 split方法得到的數(shù)組時,需做最后一個分隔符后有無內(nèi)容的檢查,否則會有拋 IndexOutOfBoundsException的風(fēng)險。說明:String str = "a,b,c,"String ary = str.split(",");/預(yù)期大于 3,結(jié)果是 3System.out.println(ary.length);14.【推薦】當(dāng)一個類有多個構(gòu)造方法,或者多個同名方法,這些方法應(yīng)該按順序放置在一起,便于閱讀。禁止用于商業(yè)用途,違者必究8 / 37 阿里巴巴 J

29、ava開發(fā)手冊15.【推薦】 類內(nèi)方法定義順序依次是:公有方法或保護(hù)方法 > 私有方法 > getter/setter方法。說明:公有方法是類的調(diào)用者和維護(hù)者最關(guān)心的方法,首屏展示最好;保護(hù)方法雖然只是子類關(guān)心,也可能是“模板設(shè)計(jì)模式”下的核心方法;而私有方法外部一般不需要特別關(guān)心,是一個黑盒實(shí)現(xiàn);因?yàn)榉椒ㄐ畔r值較低,所有 Service和 DAO的 getter/setter方法放在類體最后。16.【推薦】setter方法中,參數(shù)名稱與類成員變量名稱一致,this.成員名 = 參數(shù)名。在getter/setter方法中,盡量不要增加業(yè)務(wù)邏輯,增加排查問題的難度。反例:publi

30、c Integer getData() if (true) return data + 100; else return data - 100;17.【推薦】循環(huán)體內(nèi),字符串的連接方式,使用 StringBuilder的 append方法進(jìn)行擴(kuò)展。反例:String str = "start"for (int I = 0; I < 100; i+) str = str + "hello"說明:反編譯出的字節(jié)碼文件顯示每次循環(huán)都會 new出一個 StringBuilder對象,然后進(jìn)行append操作,最后通過 toString方法返回 String

31、對象,造成內(nèi)存資源浪費(fèi)。18.【推薦】下列情況,聲明成 final會更有提示性:1) 不需要重新賦值的變量,包括類屬性、局部變量。2) 對象參數(shù)前加 final,表示不允許修改引用的指向。3) 類方法確定不允許被重寫。19.【推薦】慎用 Object的 clone方法來拷貝對象。說明:對象的 clone方法默認(rèn)是淺拷貝,若想實(shí)現(xiàn)深拷貝需要重寫 clone方法實(shí)現(xiàn)屬性對象的拷貝。禁止用于商業(yè)用途,違者必究9 / 37 阿里巴巴 Java開發(fā)手冊20.【推薦】類成員與方法訪問控制從嚴(yán):1) 如果不允許外部直接通過 new來創(chuàng)建對象,那么構(gòu)造方法必須是 private。2) 工具類不允許有 publ

32、ic或 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)控訪問范圍。過寬泛的訪問范圍,不利于模塊解耦。思考:如果是一個 private的方法,想刪除就刪除,可是一個 public的 Se

33、rvice方法,或者一個 public的成員變量,刪除一下,不得手心冒點(diǎn)汗嗎?變量像自己的小孩,盡量在自己的視線內(nèi),變量作用域太大,如果無限制的到處跑,那么你會擔(dān)心的。禁止用于商業(yè)用途,違者必究10 / 37 阿里巴巴 Java開發(fā)手冊(五)集合處理1.【強(qiáng)制】關(guān)于 hashCode和 equals的處理,遵循如下規(guī)則:1) 只要重寫 equals,就必須重寫 hashCode。2) 因?yàn)?Set存儲的是不重復(fù)的對象,依據(jù) hashCode和 equals進(jìn)行判斷,所以 Set存儲的對象必須重寫這兩個方法。3) 如果自定義對象做為 Map的鍵,那么必須重寫 hashCode和 equals。說

34、明:String重寫了 hashCode和 equals方法,所以我們可以非常愉快地使用 String對象作為 key來使用。2.【強(qiáng)制】ArrayList的subList結(jié)果不可強(qiáng)轉(zhuǎn)成ArrayList,否則會拋出ClassCastException異常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList ;說明:subList 返回的是 ArrayList 的內(nèi)部類 SubList,并不是 ArrayList ,而是ArrayList 的一個視圖,對于 SubList子列表的所有操作最終會反映到原列表上。3

35、.【強(qiáng)制】 在 subList場景中,高度注意對原集合元素個數(shù)的修改,會導(dǎo)致子列表的遍歷、增加、刪除均產(chǎn)生 ConcurrentModificationException 異常。4.【強(qiáng)制】使用集合轉(zhuǎn)數(shù)組的方法,必須使用集合的 toArray(T array),傳入的是類型完全一樣的數(shù)組,大小就是 list.size()。說明:使用 toArray帶參方法,入?yún)⒎峙涞臄?shù)組空間不夠大時,toArray方法內(nèi)部將重新分配內(nèi)存空間,并返回新數(shù)組地址;如果數(shù)組元素大于實(shí)際所需,下標(biāo)為 list.size() 的數(shù)組元素將被置為 null,其它數(shù)組元素保持原值,因此最好將方法入?yún)?shù)組大小定義與集合元素個

36、數(shù)一致。正例:List<String> list = new ArrayList<String>(2);list.add("guan");list.add("bao");String array = new Stringlist.size();array = list.toArray(array);反例:直接使用 toArray無參方法存在問題,此方法返回值只能是 Object類,若強(qiáng)轉(zhuǎn)其它類型數(shù)組將出現(xiàn) ClassCastException錯誤。5.【強(qiáng)制】使用工具類 Arrays.asList()把數(shù)組轉(zhuǎn)換成集合時,不能使用其

37、修改集合相關(guān)的方法,它的 add/remove/clear方法會拋出 UnsupportedOperationException異常。說明:asList的返回對象是一個 Arrays內(nèi)部類,并沒有實(shí)現(xiàn)集合的修改方法。Arrays.asList體現(xiàn)的是適配器模式,只是轉(zhuǎn)換接口,后臺的數(shù)據(jù)仍是數(shù)組。String str = new String "a", "b" ;List list = Arrays.asList(str);禁止用于商業(yè)用途,違者必究11 / 37 阿里巴巴 Java開發(fā)手冊第一種情況:list.add("c"); 運(yùn)行

38、時異常。第二種情況:str0 = "gujin" 那么 list.get(0)也會隨之修改。6.【強(qiáng)制】泛型通配符<? extends T>來接收返回的數(shù)據(jù),此寫法的泛型集合不能使用 add方法,而<? super T>不能使用 get方法,做為接口調(diào)用賦值時易出錯。說明:擴(kuò)展說一下 PECS(Producer Extends Consumer Super)原則:1)頻繁往外讀取內(nèi)容的,適合用上界 Extends。2)經(jīng)常往里插入的,適合用下界 Super。7.【強(qiáng)制】不要在 foreach循環(huán)里進(jìn)行元素的 remove/add操作。remove元素

39、請使用 Iterator方式,如果并發(fā)操作,需要對 Iterator對象加鎖。反例:List<String> a = new ArrayList<String>();a.add("1");a.add("2");for (String temp : a) if ("1".equals(temp) a.remove(temp);說明:以上代碼的執(zhí)行結(jié)果肯定會出乎大家的意料,那么試一下把“1”換成“2”,會是同樣的結(jié)果嗎?正例:Iterator<String> it = a.iterator();whil

40、e (it.hasNext() String temp = it.next();if (刪除元素的條件) it.remove();8.【強(qiáng)制】 在 JDK7版本及以上,Comparator要滿足如下三個條件,不然 Arrays.sort,Collections.sort會報 IllegalArgumentException異常。說明:1) x,y的比較結(jié)果和 y,x的比較結(jié)果相反。2) x>y,y>z,則 x>z。3) x=y,則 x,z比較結(jié)果和 y,z比較結(jié)果相同。反例:下例中沒有處理相等的情況,實(shí)際使用中可能會出現(xiàn)異常:new Comparator<Student

41、>() Overridepublic int compare(Student o1, Student o2) return o1.getId() > o2.getId() ? 1 : -1;禁止用于商業(yè)用途,違者必究12 / 37 阿里巴巴 Java開發(fā)手冊9.【推薦】集合初始化時,盡量指定集合初始值大小。說明:ArrayList盡量使用 ArrayList(int initialCapacity) 初始化。10.【推薦】使用 entrySet遍歷 Map類集合 KV,而不是 keySet方式進(jìn)行遍歷。說明:keySet其實(shí)是遍歷了 2次,一次是轉(zhuǎn)為 Iterator對象,另一次是

42、從 hashMap中取出key所對應(yīng)的 value。而 entrySet只是遍歷了一次就把 key和 value都放到了 entry中,效率更高。如果是 JDK8,使用 Map.foreach方法。正例:values()返回的是 V值集合,是一個 list集合對象;keySet()返回的是 K值集合,是一個 Set集合對象;entrySet()返回的是 K-V值組合集合。11.【推薦】高度注意 Map類集合 K/V能不能存儲 null值的情況,如下表格:KeyValueSuper集合類說明HashtableConcurrentHashMapTreeMap不允許為 null不允許為 null不允

43、許為 null允許為 null不允許為 null Dictionary不允許為 null AbstractMap線程安全分段鎖技術(shù)線程不安全線程不安全允許為 null允許為 nullAbstractMapAbstractMapHashMap反例: 由于 HashMap的干擾,很多人認(rèn)為 ConcurrentHashMap是可以置入 null值,注意存儲null值時會拋出 NPE異常。12.【參考】合理利用好集合的有序性(sort)和穩(wěn)定性(order),避免集合的無序性(unsort)和不穩(wěn)定性(unorder)帶來的負(fù)面影響。說明:有序性是指遍歷的結(jié)果是按某種比較規(guī)則依次排列的。穩(wěn)定性指集合

44、每次遍歷的元素次序是一定的。如:ArrayList是 order/unsort;HashMap是 unorder/unsort;TreeSet是order/sort。13.【參考】利用 Set元素唯一的特性,可以快速對一個集合進(jìn)行去重操作,避免使用 List的contains方法進(jìn)行遍歷、對比、去重操作。(六)并發(fā)處理1.【強(qiáng)制】獲取單例對象需要保證線程安全,其中的方法也要保證線程安全。說明:資源驅(qū)動類、工具類、單例工廠類都需要注意。2.【強(qiáng)制】創(chuàng)建線程或線程池時請指定有意義的線程名稱,方便出錯時回溯。正例:public class TimerTaskThread extends Thread public TimerTaskThread() super.setName("TimerTaskThread"); .禁止用于商業(yè)用途,違者必究13 / 37 阿里巴巴

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論