《java開發(fā)手冊(cè)》word版_第1頁
《java開發(fā)手冊(cè)》word版_第2頁
《java開發(fā)手冊(cè)》word版_第3頁
《java開發(fā)手冊(cè)》word版_第4頁
《java開發(fā)手冊(cè)》word版_第5頁
已閱讀5頁,還剩26頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、 31/31Java開發(fā)手冊(cè) 目錄 TOC o 1-3 h z u HYPERLINK l _Toc476818575 前言 PAGEREF _Toc476818575 h 3 HYPERLINK l _Toc476818576 一、編程規(guī)約 PAGEREF _Toc476818576 h 4 HYPERLINK l _Toc476818577 (一) 命名規(guī)約 PAGEREF _Toc476818577 h 4 HYPERLINK l _Toc476818578 (二) 常量定義 PAGEREF _Toc476818578 h 6 HYPERLINK l _Toc476818579 (三)

2、格式規(guī)約 PAGEREF _Toc476818579 h 7 HYPERLINK l _Toc476818580 (四) OOP 規(guī)約 PAGEREF _Toc476818580 h 8 HYPERLINK l _Toc476818581 (五) 集合處理 PAGEREF _Toc476818581 h 11 HYPERLINK l _Toc476818582 (六) 并發(fā)處理 PAGEREF _Toc476818582 h 14 HYPERLINK l _Toc476818583 (七) 控制語句 PAGEREF _Toc476818583 h 16 HYPERLINK l _Toc4768

3、18584 (八) 注釋規(guī)約 PAGEREF _Toc476818584 h 17 HYPERLINK l _Toc476818585 (九) 其它 PAGEREF _Toc476818585 h 18 HYPERLINK l _Toc476818586 二、異常日志 PAGEREF _Toc476818586 h 19 HYPERLINK l _Toc476818587 (一)異常處理 PAGEREF _Toc476818587 h 19 HYPERLINK l _Toc476818588 (二)日志規(guī)約 PAGEREF _Toc476818588 h 21 HYPERLINK l _Toc

4、476818589 三、MySQL 規(guī)約 PAGEREF _Toc476818589 h 22 HYPERLINK l _Toc476818590 (一)建表規(guī)約 PAGEREF _Toc476818590 h 22 HYPERLINK l _Toc476818591 (二)索引規(guī)約 PAGEREF _Toc476818591 h 23 HYPERLINK l _Toc476818592 (三)SQL 規(guī)約 PAGEREF _Toc476818592 h 25 HYPERLINK l _Toc476818593 (四)ORM 規(guī)約 PAGEREF _Toc476818593 h 26 HYPE

5、RLINK l _Toc476818594 四、工程規(guī)約 PAGEREF _Toc476818594 h 27 HYPERLINK l _Toc476818595 (一)應(yīng)用分層 PAGEREF _Toc476818595 h 27 HYPERLINK l _Toc476818596 (二)二方庫規(guī)約 PAGEREF _Toc476818596 h 28 HYPERLINK l _Toc476818597 (三)服務(wù)器規(guī)約 PAGEREF _Toc476818597 h 29 HYPERLINK l _Toc476818598 五、安全規(guī)約 PAGEREF _Toc476818598 h 30

6、 HYPERLINK l _Toc476818599 六、附1:本規(guī)約專有名詞 PAGEREF _Toc476818599 h 30Java 開發(fā)手冊(cè)前言Java 開發(fā)手冊(cè)是某著名集團(tuán)技術(shù)團(tuán)隊(duì)的集體經(jīng)驗(yàn)總結(jié),經(jīng)歷了多次大規(guī)模一線實(shí)戰(zhàn)的檢驗(yàn)及不斷的完善,反饋給廣大開發(fā)者?,F(xiàn)代軟件行業(yè)的高速發(fā)展對(duì)于開發(fā)者的綜合素質(zhì)要求越來越高,因?yàn)椴粌H是編程知識(shí)點(diǎn),其它維度的知識(shí)點(diǎn)也會(huì)影響到軟件的最終交付質(zhì)量。比如:數(shù)據(jù)庫的表結(jié)構(gòu)和索引設(shè)計(jì)缺陷可能帶來軟件上的架構(gòu)缺陷或性能風(fēng)險(xiǎn);工程結(jié)構(gòu)混亂導(dǎo)致維護(hù)困難;沒有鑒權(quán)的漏洞代碼被黑客攻擊等等。所以本手冊(cè)以 Java 開發(fā)者為中心視角,劃分為編程規(guī)約、異常日志規(guī)約、My

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

8、有紅綠燈,沒有規(guī)定靠右行駛,誰還敢上路行駛。對(duì)軟件來說,適當(dāng)?shù)囊?guī)范和標(biāo)準(zhǔn)絕不是消滅代碼內(nèi)容的創(chuàng)造性、優(yōu)雅性,而是限制過度個(gè)性化,以一種普遍認(rèn)可的統(tǒng)一方式一起做事,提升協(xié)作效率。Java 開發(fā)手冊(cè)版本號(hào)制定團(tuán)隊(duì)更新日期備注增加前言和專有名詞說明,修正部分描述。編程規(guī)約(一) 命名規(guī)約【強(qiáng)制】 代碼中的命名均不能以下劃線或美元符號(hào)開始,也不能以下劃線或美元符號(hào)結(jié)束。反例: _name / _name / $Object / name_ / name$ / Object$【強(qiáng)制】 代碼中的命名嚴(yán)禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。說明:正確的英文拼寫和語法可以讓閱讀者易于理解,避

9、免歧義。注意,即使純拼音命名方式也要避免采用。反例: DaZhePromotion 打折 / getPingfenByName() 評(píng)分 / int 某變量 = 3 正例: alibaba / taobao / youku / hangzhou 等國(guó)際通用的名稱,可視同英文?!緩?qiáng)制】類名使用 UpperCamelCase 風(fēng)格,必須遵從駝峰形式,但以下情形例外:(領(lǐng)域模型的相關(guān)命名)DO / BO / DTO / VO 等。正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion 反例:macroPolo / UserDo /

10、XMLService / TCPUDPDeal / TAPromotion【強(qiáng)制】方法名、參數(shù)名、成員變量、局部變量都統(tǒng)一使用 lowerCamelCase 風(fēng)格,必須遵從駝峰形式。正例: localValue / getHttpMessage() / inputUserId【強(qiáng)制】常量命名全部大寫,單詞間用下劃線隔開,力求語義表達(dá)完整清楚,不要嫌名字長(zhǎng)。正例: MAX_STOCK_COUNT反例: MAX_COUNT【強(qiáng)制】抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結(jié)尾;測(cè)試類命名以它要測(cè)試的類的名稱開始,以 Test 結(jié)尾?!緩?qiáng)制】中括號(hào)是數(shù)

11、組類型的一部分,數(shù)組定義如下:String args; 反例:使用 String args的方式來定義?!緩?qiáng)制】POJO 類中布爾類型的變量,都不要加 is,否則部分框架解析會(huì)引起序列化錯(cuò)誤。反例:定義為基本數(shù)據(jù)類型 Boolean isSuccess;的屬性,它的方法也是 isSuccess(),RPC框架在反向解析的時(shí)候,“以為”對(duì)應(yīng)的屬性名稱是 success,導(dǎo)致屬性獲取不到,進(jìn)而拋出異常。【強(qiáng)制】包名統(tǒng)一使用小寫,點(diǎn)分隔符之間有且僅有一個(gè)自然語義的英語單詞。包名統(tǒng)一使用單數(shù)形式,但是類名如果有復(fù)數(shù)含義,類名可以使用復(fù)數(shù)形式。正例: 應(yīng)用工具類包名為 com.alibaba.open.

12、util、類名為 MessageUtils(此規(guī)則參考 spring 的框架結(jié)構(gòu))【強(qiáng)制】杜絕完全不規(guī)范的縮寫,避免望文不知義。反例: AbstractClass“縮寫”命名成 AbsClass;condition“縮寫”命名成 condi,此類隨意縮寫嚴(yán)重降低了代碼的可閱讀性。11. 【推薦】如果使用到了設(shè)計(jì)模式,建議在類名中體現(xiàn)出具體模式。說明:將設(shè)計(jì)模式體現(xiàn)在名字中,有利于閱讀者快速理解架構(gòu)設(shè)計(jì)思想。正例:public class OrderFactory; public class LoginProxy; public class ResourceObserver;12. 【推薦】接口

13、類中的方法和屬性不要加任何修飾符號(hào)(public 也不要加),保持代碼的簡(jiǎn)潔性,并加上有效的 Javadoc 注釋。盡量不要在接口里定義變量,如果一定要定義變量,肯定是與接口方法相關(guān),并且是整個(gè)應(yīng)用的基礎(chǔ)常量。正例:接口方法簽名:void f();接口基礎(chǔ)常量表示:String COMPANY = alibaba; 反例:接口方法定義:public abstract void f();說明:JDK8 中接口允許有默認(rèn)實(shí)現(xiàn),那么這個(gè) default 方法,是對(duì)所有實(shí)現(xiàn)類都有價(jià)值的默認(rèn)實(shí)現(xiàn)。13. 接口和實(shí)現(xiàn)類的命名有兩套規(guī)則:1)【強(qiáng)制】對(duì)于 Service 和 DAO 類,基于 SOA 的理念

14、,暴露出來的服務(wù)一定是接口,內(nèi)部的實(shí)現(xiàn)類用 Impl 的后綴與接口區(qū)別。正例:CacheServiceImpl 實(shí)現(xiàn) CacheService 接口。2)【推薦】 如果是形容能力的接口名稱,取對(duì)應(yīng)的形容詞做接口名(通常是able 的形式)。正例:AbstractTranslator 實(shí)現(xiàn) Translatable。14. 【參考】枚舉類名建議帶上 Enum 后綴,枚舉成員名稱需要全大寫,單詞間用下劃線隔開。說明:枚舉其實(shí)就是特殊的常量類,且構(gòu)造方法被默認(rèn)強(qiáng)制是私有。正例:枚舉名字:DealStatusEnum,成員名稱:SUCCESS / UNKOWN_REASON?!緟⒖肌扛鲗用?guī)約:Se

15、rvice/DAO 層方法命名規(guī)約1) 獲取單個(gè)對(duì)象的方法用 get 做前綴。2) 獲取多個(gè)對(duì)象的方法用 list 做前綴。3) 獲取統(tǒng)計(jì)值的方法用 count 做前綴。4) 插入的方法用 save(推薦)或 insert 做前綴。5) 刪除的方法用 remove(推薦)或 delete 做前綴。6) 修改的方法用 update 做前綴。B) 領(lǐng)域模型命名規(guī)約1) 數(shù)據(jù)對(duì)象:xxxDO,xxx 即為數(shù)據(jù)表名。2) 數(shù)據(jù)傳輸對(duì)象:xxxDTO,xxx 為業(yè)務(wù)領(lǐng)域相關(guān)的名稱。3) 展示對(duì)象:xxxVO,xxx 一般為網(wǎng)頁名稱。4) POJO 是 DO/DTO/BO/VO 的統(tǒng)稱,禁止命名成 xxx

16、POJO。(二) 常量定義1. 【強(qiáng)制】不允許出現(xiàn)任何魔法值(即未經(jīng)定義的常量)直接出現(xiàn)在代碼中。反例: String key = Id#taobao_+tradeId; cache.put(key, value);【強(qiáng)制】long 或者 Long 初始賦值時(shí),必須使用大寫的 L,不能是小寫的 l,小寫容易跟數(shù)字 1 混淆,造成誤解。說明:Long a = 2l; 寫的是數(shù)字的 21,還是 Long 型的 2?【推薦】不要使用一個(gè)常量類維護(hù)所有常量,應(yīng)該按常量功能進(jìn)行歸類,分開維護(hù)。如:緩存相關(guān)的常量放在類:CacheConsts 下;系統(tǒng)配置相關(guān)的常量放在類:ConfigConsts 下。說

17、明:大而全的常量類,非得使用查找功能才能定位到修改的常量,不利于理解和維護(hù)?!就扑]】常量的復(fù)用層次有五層:跨應(yīng)用共享常量、應(yīng)用內(nèi)共享常量、子工程內(nèi)共享常量、包內(nèi)共享常量、類內(nèi)共享常量。1) 跨應(yīng)用共享常量:放置在二方庫中,通常是 client.jar 中的 constant 目錄下。2) 應(yīng)用內(nèi)共享常量:放置在一方庫的 modules 中的 constant 目錄下。反例:易懂變量也要統(tǒng)一定義成應(yīng)用內(nèi)共享常量,兩位攻城師在兩個(gè)類中分別定義了表示“是”的變量:類 A 中:public static final String YES = yes; 類 B 中:public static final

18、 String YES = y;A.YES.equals(B.YES),預(yù)期是 true,但實(shí)際返回為 false,導(dǎo)致產(chǎn)生線上問題。3) 子工程內(nèi)部共享常量:即在當(dāng)前子工程的 constant 目錄下。4) 包內(nèi)共享常量:即在當(dāng)前包下單獨(dú)的 constant 目錄下。5) 類內(nèi)共享常量:直接在類內(nèi)部 private static final 定義?!就扑]】如果變量值僅在一個(gè)范圍內(nèi)變化用 Enum 類。如果還帶有名稱之外的延伸屬性,必須使用 Enum 類,下面正例中的數(shù)字就是延伸信息,表示星期幾。正例:public Enum MONDAY(1), TUESDAY(2), WEDNESDAY(3

19、), THURSDAY(4), FRIDAY(5), SATURDAY(6),SUNDAY(7);(三) 格式規(guī)約【強(qiáng)制】大括號(hào)的使用約定。如果是大括號(hào)內(nèi)為空,則簡(jiǎn)潔地寫成即可,不需要換行;如果是非空代碼塊則:1) 左大括號(hào)前不換行。2) 左大括號(hào)后換行。3) 右大括號(hào)前換行。4) 右大括號(hào)后還有 else 等代碼則不換行;表示終止右大括號(hào)后必須換行?!緩?qiáng)制】 左括號(hào)和后一個(gè)字符之間不出現(xiàn)空格;同樣,右括號(hào)和前一個(gè)字符之間也不出現(xiàn)空格。詳見第 5 條下方正例提示?!緩?qiáng)制】if/for/while/switch/do 等保留字與左右括號(hào)之間都必須加空格。【強(qiáng)制】任何運(yùn)算符左右必須加一個(gè)空格。說明

20、:運(yùn)算符包括賦值運(yùn)算符=、邏輯運(yùn)算符&、加減乘除符號(hào)、三目運(yùn)算符等?!緩?qiáng)制】縮進(jìn)采用 4 個(gè)空格,禁止使用 tab 字符。說明:如果使用 tab 縮進(jìn),必須設(shè)置 1 個(gè) tab 為 4 個(gè)空格。IDEA 設(shè)置 tab 為 4 個(gè)空格時(shí),請(qǐng)勿勾選 Use tab character;而在 eclipse 中,必須勾選 insert spaces for tabs。正例: (涉及 1-5 點(diǎn))public static void main(String args) / 縮進(jìn) 4 個(gè)空格String say = hello;運(yùn)算符的左右必須有一個(gè)空格 int flag = 0;關(guān)鍵詞 if 與括號(hào)之

21、間必須有一個(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.println(world);/ 右大括號(hào)前換行,右大括號(hào)后有 else,不用換行 else System.out.println(ok);/ 在右大括號(hào)后直接結(jié)束,則必須換行6. 【強(qiáng)制】單行字符數(shù)限制不超過 120 個(gè),超出需要換行,換行時(shí)遵循如下原則:1) 第二行相對(duì)第一行縮進(jìn) 4 個(gè)空格,從第三行開始,不再繼續(xù)縮進(jìn),參考示例。2) 運(yùn)算符與下文一起換行。3)

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

23、ang);/參數(shù)很多的方法調(diào)用可能超過 120 個(gè)字符,不要在逗號(hào)前換行method(args1, args2, args3, .argsX);【強(qiáng)制】方法參數(shù)在定義和傳入時(shí),多個(gè)參數(shù)逗號(hào)后邊必須加空格。正例:下例中實(shí)參的a,后邊必須要有一個(gè)空格。method(a, b, c);【強(qiáng)制】IDE 的 text file encoding 設(shè)置為 UTF-8; IDE 中文件的換行符使用 Unix 格式,不要使用 windows 格式?!就扑]】沒有必要增加若干空格來使某一行的字符與上一行的相應(yīng)字符對(duì)齊。正例:int a = 3; long b = 4L; float c = 5F;StringBu

24、ffer sb = new StringBuffer();說明:增加 sb 這個(gè)變量,如果需要對(duì)齊,則給 a、b、c 都要增加幾個(gè)空格,在變量比較多的情況下,是一種累贅的事情。10. 【推薦】方法體內(nèi)的執(zhí)行語句組、變量的定義語句組、不同的業(yè)務(wù)邏輯之間或者不同的語義之間插入一個(gè)空行。相同業(yè)務(wù)邏輯和語義之間不需要插入空行。說明:沒有必要插入多行空格進(jìn)行隔開。(四) OOP 規(guī)約【強(qiáng)制】避免通過一個(gè)類的對(duì)象引用訪問此類的靜態(tài)變量或靜態(tài)方法,無謂增加編譯器解析成本,直接用類名來訪問即可。【強(qiáng)制】所有的覆寫方法,必須加Override 注解。反例:getObject()與 get0bject()的問題。

25、一個(gè)是字母的 O,一個(gè)是數(shù)字的 0,加Override可以準(zhǔn)確判斷是否覆蓋成功。另外,如果在抽象類中對(duì)方法簽名進(jìn)行修改,其實(shí)現(xiàn)類會(huì)馬上編譯報(bào)錯(cuò)?!緩?qiáng)制】相同參數(shù)類型,相同業(yè)務(wù)含義,才可以使用 Java 的可變參數(shù),避免使用 Object。說明:可變參數(shù)必須放置在參數(shù)列表的最后。(提倡同學(xué)們盡量不用可變參數(shù)編程)正例:public User getUsers(String type, Integer. ids)【強(qiáng)制】外部正在調(diào)用或者二方庫依賴的接口,不允許修改方法簽名,避免對(duì)接口調(diào)用方產(chǎn)生影響。接口過時(shí)必須加Deprecated 注解,并清晰地說明采用的新接口或者新服務(wù)是什么?!緩?qiáng)制】不能使用

26、過時(shí)的類或方法。說明:.URLDecoder 中的方法 decode(String encodeStr) 這個(gè)方法已經(jīng)過時(shí),應(yīng)該使用雙參數(shù) decode(String source, String encode)。接口提供方既然明確是過時(shí)接口,那么有義務(wù)同時(shí)提供新的接口;作為調(diào)用方來說,有義務(wù)去考證過時(shí)方法的新實(shí)現(xiàn)是什么?!緩?qiáng)制】Object 的 equals 方法容易拋空指針異常,應(yīng)使用常量或確定有值的對(duì)象來調(diào)用equals。正例: test.equals(object); 反例: object.equals(test);說明:推薦使用 java.util.Objects#equals (J

27、DK7 引入的工具類)7. 【強(qiáng)制】所有的相同類型的包裝類對(duì)象之間值的比較,全部使用 equals 方法比較。說明:對(duì)于 Integer var = ?在-128 至 127 之間的賦值,Integer 對(duì)象是在 IntegerCache.cache 產(chǎn)生,會(huì)復(fù)用已有對(duì)象,這個(gè)區(qū)間內(nèi)的 Integer 值可以直接使用=進(jìn)行判斷,但是這個(gè)區(qū)間之外的所有數(shù)據(jù),都會(huì)在堆上產(chǎn)生,并不會(huì)復(fù)用已有對(duì)象,這是一個(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ù)必

28、須使用包裝數(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)用失敗,異常退出?!緩?qiáng)制】定義 DO/DTO/VO 等 POJO 類時(shí),不要設(shè)定任

29、何屬性默認(rèn)值。反例:POJO 類的 gmtCreate 默認(rèn)值為 new Date();但是這個(gè)屬性在數(shù)據(jù)提取時(shí)并沒有置入具體值,在更新其它字段時(shí)又附帶更新了此字段,導(dǎo)致創(chuàng)建時(shí)間被修改成當(dāng)前時(shí)間?!緩?qiáng)制】序列化類新增屬性時(shí),請(qǐng)不要修改 serialVersionUID 字段,避免反序列失?。蝗绻耆患嫒萆?jí),避免反序列化混亂,那么請(qǐng)修改 serialVersionUID 值。說明:注意 serialVersionUID 不一致會(huì)拋出序列化運(yùn)行時(shí)異常?!緩?qiáng)制】構(gòu)造方法里面禁止加入任何業(yè)務(wù)邏輯,如果有初始化邏輯,請(qǐng)放在 init 方法中?!緩?qiáng)制】POJO 類必須寫 toString 方法。使用

30、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)。說明:String str = a,b,c,;String ary = str.split(,);/預(yù)期大于 3,結(jié)果是 3System.out.prin

31、tln(ary.length);14. 【推薦】當(dāng)一個(gè)類有多個(gè)構(gòu)造方法,或者多個(gè)同名方法,這些方法應(yīng)該按順序放置在一起,便于閱讀。15. 【推薦】 類內(nèi)方法定義順序依次是:公有方法或保護(hù)方法 私有方法 getter/setter方法。說明:公有方法是類的調(diào)用者和維護(hù)者最關(guān)心的方法,首屏展示最好;保護(hù)方法雖然只是子類關(guān)心,也可能是“模板設(shè)計(jì)模式”下的核心方法;而私有方法外部一般不需要特別關(guān)心,是一個(gè)黑盒實(shí)現(xiàn);因?yàn)榉椒ㄐ畔r(jià)值較低,所有 Service 和 DAO 的 getter/setter 方法放在類體最后。16. 【推薦】setter 方法中,參數(shù)名稱與類成員變量名稱一致,this.成員名

32、 = 參數(shù)名。在getter/setter 方法中,盡量不要增加業(yè)務(wù)邏輯,增加排查問題的難度。反例:public 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)都會(huì) new 出一個(gè) StringBuilder 對(duì)象,然后進(jìn)行

33、append 操作,最后通過 toString 方法返回 String 對(duì)象,造成內(nèi)存資源浪費(fèi)。18. 【推薦】下列情況,聲明成 final 會(huì)更有提示性:1) 不需要重新賦值的變量,包括類屬性、局部變量。2) 對(duì)象參數(shù)前加 final,表示不允許修改引用的指向。3) 類方法確定不允許被重寫。19. 【推薦】慎用 Object 的 clone 方法來拷貝對(duì)象。說明:對(duì)象的 clone 方法默認(rèn)是淺拷貝,若想實(shí)現(xiàn)深拷貝需要重寫 clone 方法實(shí)現(xiàn)屬性對(duì)象的拷貝。20. 【推薦】類成員與方法訪問控制從嚴(yán):1) 如果不允許外部直接通過 new 來創(chuàng)建對(duì)象,那么構(gòu)造方法必須是 private。2)

34、工具類不允許有 public 或 default 構(gòu)造方法。3) 類非 static 成員變量并且與子類共享,必須是 protected。4) 類非 static 成員變量并且僅在本類使用,必須是 private。5) 類 static 成員變量如果僅在本類使用,必須是 private。6) 若是 static 成員變量,必須考慮是否為 final。7) 類成員方法只供類內(nèi)部調(diào)用,必須是 private。8) 類成員方法只對(duì)繼承類公開,那么限制為 protected。說明:任何類、方法、參數(shù)、變量,嚴(yán)控訪問范圍。過寬泛的訪問范圍,不利于模塊解耦。思考:如果是一個(gè) private 的方法,想刪除

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

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

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

38、集合元素個(gè)數(shù)一致。正例:List list = new ArrayList(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 錯(cuò)誤。【強(qiáng)制】使用工具類 Arrays.asList()把數(shù)組轉(zhuǎn)換成集合時(shí),不能使用其修改集合相關(guān)的方法,它的 add/remove/clear 方法會(huì)拋出 Unsupport

39、edOperationException 異常。說明:asList 的返回對(duì)象是一個(gè) Arrays 內(nèi)部類,并沒有實(shí)現(xiàn)集合的修改方法。Arrays.asList體現(xiàn)的是適配器模式,只是轉(zhuǎn)換接口,后臺(tái)的數(shù)據(jù)仍是數(shù)組。String str = new String a, b ;List list = Arrays.asList(str);第一種情況:list.add(c); 運(yùn)行時(shí)異常。第二種情況:str0 = gujin; 那么 list.get(0)也會(huì)隨之修改?!緩?qiáng)制】泛型通配符來接收返回的數(shù)據(jù),此寫法的泛型集合不能使用 add 方法,而不能使用 get 方法,做為接口調(diào)用賦值時(shí)易出錯(cuò)。說明

40、:擴(kuò)展說一下 PECS(Producer Extends Consumer Super)原則:1)頻繁往外讀取內(nèi)容的,適合用上界 Extends。2)經(jīng)常往里插入的,適合用下界 Super?!緩?qiáng)制】不要在 foreach 循環(huán)里進(jìn)行元素的 remove/add 操作。remove 元素請(qǐng)使用 Iterator方式,如果并發(fā)操作,需要對(duì) Iterator 對(duì)象加鎖。反例:List a = new ArrayList(); a.add(1);a.add(2);for (String temp : a) if (1.equals(temp) a.remove(temp);說明:以上代碼的執(zhí)行結(jié)果肯定

41、會(huì)出乎大家的意料,那么試一下把“1”換成“2”,會(huì)是同樣的結(jié)果嗎?正例:Iterator it = a.iterator(); while (it.hasNext() String temp = it.next(); if (刪除元素的條件) it.remove();8. 【強(qiáng)制】 在 JDK7 版本及以上,Comparator 要滿足如下三個(gè)條件,不然 Arrays.sort,Collections.sort 會(huì)報(bào) IllegalArgumentException 異常。說明:1) x,y 的比較結(jié)果和 y,x 的比較結(jié)果相反。2) xy,yz,則 xz。3) x=y,則 x,z 比較結(jié)果和

42、 y,z 比較結(jié)果相同。反例:下例中沒有處理相等的情況,實(shí)際使用中可能會(huì)出現(xiàn)異常:new Comparator() Overridepublic int compare(Student o1, Student o2) return o1.getId() o2.getId() ? 1 : -1;【推薦】集合初始化時(shí),盡量指定集合初始值大小。說明:ArrayList 盡量使用 ArrayList(int initialCapacity) 初始化?!就扑]】使用 entrySet 遍歷 Map 類集合 KV,而不是 keySet 方式進(jìn)行遍歷。說明:keySet 其實(shí)是遍歷了 2 次,一次是轉(zhuǎn)為 It

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

44、nullDictionary線程安全ConcurrentHashMap不允許為 null不允許為 nullAbstractMap分段鎖技術(shù)TreeMap不允許為 null允許為 nullAbstractMap線程不安全HashMap允許為 null允許為 nullAbstractMap線程不安全反例: 由于 HashMap 的干擾,很多人認(rèn)為 ConcurrentHashMap 是可以置入 null 值,注意存儲(chǔ)null 值時(shí)會(huì)拋出 NPE 異常。12. 【參考】合理利用好集合的有序性(sort)和穩(wěn)定性(order),避免集合的無序性(unsort)和不穩(wěn)定性(unorder)帶來的負(fù)面影響

45、。說明:有序性是指遍歷的結(jié)果是按某種比較規(guī)則依次排列的。穩(wěn)定性指集合每次遍歷的元素次序是一定的。如:ArrayList 是 order/unsort;HashMap 是 unorder/unsort;TreeSet 是order/sort。13. 【參考】利用 Set 元素唯一的特性,可以快速對(duì)一個(gè)集合進(jìn)行去重操作,避免使用 List 的contains 方法進(jìn)行遍歷、對(duì)比、去重操作。(六) 并發(fā)處理【強(qiáng)制】獲取單例對(duì)象需要保證線程安全,其中的方法也要保證線程安全。說明:資源驅(qū)動(dòng)類、工具類、單例工廠類都需要注意?!緩?qiáng)制】創(chuàng)建線程或線程池時(shí)請(qǐng)指定有意義的線程名稱,方便出錯(cuò)時(shí)回溯。正例:publi

46、c class TimerTaskThread extends Thread public TimerTaskThread() super.setName(TimerTaskThread);.【強(qiáng)制】線程資源必須通過線程池提供,不允許在應(yīng)用中自行顯式創(chuàng)建線程。說明:使用線程池的好處是減少在創(chuàng)建和銷毀線程上所花的時(shí)間以及系統(tǒng)資源的開銷,解決資源不足的問題。如果不使用線程池,有可能造成系統(tǒng)創(chuàng)建大量同類線程而導(dǎo)致消耗完內(nèi)存或者“過度切換”的問題。【強(qiáng)制】線程池不允許使用 Executors 去創(chuàng)建,而是通過 ThreadPoolExecutor 的方式,這樣的處理方式讓寫的同學(xué)更加明確線程池的運(yùn)行規(guī)

47、則,規(guī)避資源耗盡的風(fēng)險(xiǎn)。說明:Executors 返回的線程池對(duì)象的弊端如下:1)FixedThreadPool 和 SingleThreadPool:允許的請(qǐng)求隊(duì)列長(zhǎng)度為 Integer.MAX_VALUE,可能會(huì)堆積大量的請(qǐng)求,從而導(dǎo)致 OOM。2)CachedThreadPool 和 ScheduledThreadPool:允許的創(chuàng)建線程數(shù)量為 Integer.MAX_VALUE,可能會(huì)創(chuàng)建大量的線程,從而導(dǎo)致 OOM?!緩?qiáng)制】SimpleDateFormat 是線程不安全的類,一般不要定義為 static 變量,如果定義為static,必須加鎖,或者使用 DateUtils 工具類。正

48、例:注意線程安全,使用 DateUtils。亦推薦如下處理:private static final ThreadLocal df = new ThreadLocal() Overrideprotected DateFormat initialValue() return new SimpleDateFormat(yyyy-MM-dd);說明:如果是 JDK8 的應(yīng)用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter 代替 Simpledateformatter,官方給出的解釋:simple beautiful

49、strong immutable thread-safe?!緩?qiáng)制】高并發(fā)時(shí),同步調(diào)用應(yīng)該去考量鎖的性能損耗。能用無鎖數(shù)據(jù)結(jié)構(gòu),就不要用鎖;能鎖區(qū)塊,就不要鎖整個(gè)方法體;能用對(duì)象鎖,就不要用類鎖?!緩?qiáng)制】對(duì)多個(gè)資源、數(shù)據(jù)庫表、對(duì)象同時(shí)加鎖時(shí),需要保持一致的加鎖順序,否則可能會(huì)造成死鎖。說明:線程一需要對(duì)表 A、B、C 依次全部加鎖后才可以進(jìn)行更新操作,那么線程二的加鎖順序也必須是 A、B、C,否則可能出現(xiàn)死鎖?!緩?qiáng)制】并發(fā)修改同一記錄時(shí),避免更新丟失,需要加鎖。要么在應(yīng)用層加鎖,要么在緩存加鎖,要么在數(shù)據(jù)庫層使用樂觀鎖,使用 version 作為更新依據(jù)。說明:如果每次訪問沖突概率小于 20%,

50、推薦使用樂觀鎖,否則使用悲觀鎖。樂觀鎖的重試次數(shù)不得小于 3 次?!緩?qiáng)制】多線程并行處理定時(shí)任務(wù)時(shí),Timer 運(yùn)行多個(gè) TimeTask 時(shí),只要其中之一沒有捕獲拋出的異常,其它任務(wù)便會(huì)自動(dòng)終止運(yùn)行,使用 ScheduledExecutorService 則沒有這個(gè)問題。10. 【推薦】使用 CountDownLatch 進(jìn)行異步轉(zhuǎn)同步操作,每個(gè)線程退出前必須調(diào)用 countDown方法,線程執(zhí)行代碼注意 catch 異常,確保 countDown 方法可以執(zhí)行,避免主線程無法執(zhí)行至 await 方法,直到超時(shí)才返回結(jié)果。說明:注意,子線程拋出異常堆棧,不能在主線程 try-catch 到。

51、11. 【推薦】避免 Random 實(shí)例被多線程使用,雖然共享該實(shí)例是線程安全的,但會(huì)因競(jìng)爭(zhēng)同一seed 導(dǎo)致的性能下降。說明:Random 實(shí)例包括 java.util.Random 的實(shí)例或者 Math.random()實(shí)例。正例:在 JDK7 之后,可以直接使用 API ThreadLocalRandom,在 JDK7 之前,可以做到每個(gè)線程一個(gè)實(shí)例。12. 【推薦】在并發(fā)場(chǎng)景下,通過雙重檢查鎖(double-checked locking)實(shí)現(xiàn)延遲初始化的優(yōu)化問題隱患(可參考 The Double-Checked Locking is Broken Declaration),推薦問題解

52、決方案中較為簡(jiǎn)單一種(適用于 JDK5 及以上版本),將目標(biāo)屬性聲明為 volatile 型。反例:class Foo private Helper helper = null; public Helper getHelper() if (helper = null) synchronized(this) if (helper = null)helper = new Helper();return helper;/ other functions and members.13. 【參考】volatile 解決多線程內(nèi)存不可見問題。對(duì)于一寫多讀,是可以解決變量同步問題,但是如果多寫,同樣無法解決

53、線程安全問題。如果是 count+操作,使用如下類實(shí)現(xiàn):AtomicInteger count = new AtomicInteger(); count.addAndGet(1); 如果是 JDK8,推薦使用 LongAdder 對(duì)象,比 AtomicLong 性能更好(減少樂觀鎖的重試次數(shù))?!緟⒖肌?HashMap 在容量不夠進(jìn)行 resize 時(shí)由于高并發(fā)可能出現(xiàn)死鏈,導(dǎo)致 CPU 飆升,在開發(fā)過程中注意規(guī)避此風(fēng)險(xiǎn)?!緟⒖肌縏hreadLocal 無法解決共享對(duì)象的更新問題,ThreadLocal 對(duì)象建議使用 static修飾。這個(gè)變量是針對(duì)一個(gè)線程內(nèi)所有操作共有的,所以設(shè)置為靜態(tài)變量

54、,所有此類實(shí)例共享此靜態(tài)變量 ,也就是說在類第一次被使用時(shí)裝載,只分配一塊存儲(chǔ)空間,所有此類的對(duì)象(只要是這個(gè)線程內(nèi)定義的)都可以操控這個(gè)變量。(七) 控制語句【強(qiáng)制】在一個(gè) switch 塊內(nèi),每個(gè) case 要么通過 break/return 等來終止,要么注釋說明程序?qū)⒗^續(xù)執(zhí)行到哪一個(gè) case 為止;在一個(gè) switch 塊內(nèi),都必須包含一個(gè) default 語句并且放在最后,即使它什么代碼也沒有。【強(qiáng)制】在 if/else/for/while/do 語句中必須使用大括號(hào),即使只有一行代碼,避免使用下面的形式:if (condition) statements;【推薦】推薦盡量少用 e

55、lse, if-else 的方式可以改寫成:if (condition) .return obj;/ 接著寫 else 的業(yè)務(wù)邏輯代碼;說明:如果非得使用 if().else if().else.方式表達(dá)邏輯,【強(qiáng)制】請(qǐng)勿超過 3 層,超過請(qǐng)使用狀態(tài)設(shè)計(jì)模式。正例:邏輯上超過 3 層的 if-else 代碼可以使用衛(wèi)語句,或者狀態(tài)模式來實(shí)現(xiàn)。【推薦】除常用方法(如 getXxx/isXxx)等外,不要在條件判斷中執(zhí)行其它復(fù)雜的語句,將復(fù)雜邏輯判斷的結(jié)果賦值給一個(gè)有意義的布爾變量名,以提高可讀性。說明:很多 if 語句內(nèi)的邏輯相當(dāng)復(fù)雜,閱讀者需要分析條件表達(dá)式的最終結(jié)果,才能明確什么樣的條件執(zhí)行

56、什么樣的語句,那么,如果閱讀者分析邏輯表達(dá)式錯(cuò)誤呢?正例:/偽代碼如下boolean existed = (file.open(fileName, w) != null) & (.) | (.); if (existed) .反例:if (file.open(fileName, w) != null) & (.) | (.) .【推薦】循環(huán)體中的語句要考量性能,以下操作盡量移至循環(huán)體外處理,如定義對(duì)象、變量、獲取數(shù)據(jù)庫連接,進(jìn)行不必要的 try-catch 操作(這個(gè) try-catch 是否可以移至循環(huán)體外)?!就扑]】接口入?yún)⒈Wo(hù),這種場(chǎng)景常見的是用于做批量操作的接口。【參考】方法中需要進(jìn)行

57、參數(shù)校驗(yàn)的場(chǎng)景:1) 調(diào)用頻次低的方法。2) 執(zhí)行時(shí)間開銷很大的方法,參數(shù)校驗(yàn)時(shí)間幾乎可以忽略不計(jì),但如果因?yàn)閰?shù)錯(cuò)誤導(dǎo)致中間執(zhí)行回退,或者錯(cuò)誤,那得不償失。3) 需要極高穩(wěn)定性和可用性的方法。4) 對(duì)外提供的開放接口,不管是 RPC/API/HTTP 接口。5) 敏感權(quán)限入口。8. 【參考】方法中不需要參數(shù)校驗(yàn)的場(chǎng)景:1) 極有可能被循環(huán)調(diào)用的方法,不建議對(duì)參數(shù)進(jìn)行校驗(yàn)。但在方法說明里必須注明外部參數(shù)檢查要求。2) 底層的方法調(diào)用頻度都比較高,一般不校驗(yàn)。畢竟是像純凈水過濾的最后一道,參數(shù)錯(cuò)誤不太可能到底層才會(huì)暴露問題。一般 DAO 層與 Service 層都在同一個(gè)應(yīng)用中,部署在同一臺(tái)服務(wù)

58、器中,所以 DAO 的參數(shù)校驗(yàn),可以省略。3) 被聲明成 private 只會(huì)被自己代碼所調(diào)用的方法,如果能夠確定調(diào)用方法的代碼傳入?yún)?shù)已經(jīng)做過檢查或者肯定不會(huì)有問題,此時(shí)可以不校驗(yàn)參數(shù)。(八) 注釋規(guī)約【強(qiáng)制】類、類屬性、類方法的注釋必須使用 Javadoc 規(guī)范,使用/*內(nèi)容*/格式,不得使用/xxx 方式。說明:在 IDE 編輯窗口中,Javadoc 方式會(huì)提示相關(guān)注釋,生成 Javadoc 可以正確輸出相應(yīng)注釋;在 IDE 中,工程調(diào)用方法時(shí),不進(jìn)入方法即可懸浮提示方法、參數(shù)、返回值的意義,提高閱讀效率?!緩?qiáng)制】所有的抽象方法(包括接口中的方法)必須要用 Javadoc 注釋、除了返回

59、值、參數(shù)、異常說明外,還必須指出該方法做什么事情,實(shí)現(xiàn)什么功能。說明:對(duì)子類的實(shí)現(xiàn)要求,或者調(diào)用注意事項(xiàng),請(qǐng)一并說明。【強(qiáng)制】所有的類都必須添加創(chuàng)建者信息?!緩?qiáng)制】方法內(nèi)部單行注釋,在被注釋語句上方另起一行,使用/注釋。方法內(nèi)部多行注釋使用/* */注釋,注意與代碼對(duì)齊?!緩?qiáng)制】所有的枚舉類型字段必須要有注釋,說明每個(gè)數(shù)據(jù)項(xiàng)的用途?!就扑]】與其“半吊子”英文來注釋,不如用中文注釋把問題說清楚。專有名詞與關(guān)鍵字保持英文原文即可。反例:“TCP 連接超時(shí)”解釋成“傳輸控制協(xié)議連接超時(shí)”,理解反而費(fèi)腦筋?!就扑]】代碼修改的同時(shí),注釋也要進(jìn)行相應(yīng)的修改,尤其是參數(shù)、返回值、異常、核心邏輯等的修改。說明

60、:代碼與注釋更新不同步,就像路網(wǎng)與導(dǎo)航軟件更新不同步一樣,如果導(dǎo)航軟件嚴(yán)重滯后,就失去了導(dǎo)航的意義?!緟⒖肌孔⑨尩舻拇a盡量要配合說明,而不是簡(jiǎn)單的注釋掉。說明:代碼被注釋掉有兩種可能性:1)后續(xù)會(huì)恢復(fù)此段代碼邏輯。2)永久不用。前者如果沒有備注信息,難以知曉注釋動(dòng)機(jī)。后者建議直接刪掉(代碼倉(cāng)庫保存了歷史代碼)?!緟⒖肌繉?duì)于注釋的要求:第一、能夠準(zhǔn)確反應(yīng)設(shè)計(jì)思想和代碼邏輯;第二、能夠描述業(yè)務(wù)含義,使別的程序員能夠迅速了解到代碼背后的信息。完全沒有注釋的大段代碼對(duì)于閱讀者形同天書,注釋是給自己看的,即使隔很長(zhǎng)時(shí)間,也能清晰理解當(dāng)時(shí)的思路;注釋也是給繼任者看的,使其能夠快速接替自己的工作?!緟⒖肌?/p>

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論