個人編程時日雖說不短,但整體項目經(jīng)驗感覺上還是比較欠缺,而且個人的編程風格并未形成,為了使自己的編程更加讓人賞心悅目(而不是傷心)最近看了阿里的java開發(fā)編程的規(guī)約希望對自己的編程風格有些正面的影響,下面是我的一些筆記和總結(jié): 一、編程規(guī)約 (一) 命名規(guī)約 1. 【強制】所有編程相關(guān)命名均不能以下劃線或美元符號開始,也不能以下劃線或美元符號結(jié)束。 反例: _name / __name /
反例:
StringBuffer sb = new StringBuffer(); //超過120個字符的情況下,不要在括號前換行 sb.append("zi").append("xin")…append ("huang"); //參數(shù)很多的方法調(diào)用也超過120個字符,逗號后才是換行處 method(args1, args2, args3, ... , argsX);【強制】方法參數(shù)在定義和傳入時,多個參數(shù)逗號后邊必須加空格。 正例:下例中實參的”a”,后邊必須要有一個空格。 method(“a”, “b”, “c”);【推薦】沒有必要增加若干空格來使某一行的字符與上一行的相應(yīng)字符對齊。 正例: int a = 3; long b = 4L; float c = 5F; StringBuffer sb = new StringBuffer(); 說明:增加sb這個變量,如果需要對齊,則給a、b、c都要增加幾個空格,在變量比較多的情況下,是一種累贅的事情。 【強制】IDE的text file encoding設(shè)置為UTF-8; IDE中文件的換行符使用Unix格式,不要使用windows格式。 10.【推薦】方法體內(nèi)的執(zhí)行語句組、變量的定義語句組、不同的業(yè)務(wù)邏輯之間或者不同的語義之間插入一個空行。相同業(yè)務(wù)邏輯和語義之間不需要插入空行。 說明:沒有必要插入多行空格進行隔開。 (四) OOP規(guī)約 【強制】避免通過一個類的對象引用訪問此類的靜態(tài)變量或靜態(tài)方法,無謂增加編譯器解析成本,直接用類名來訪問即可。 【強制】所有的覆寫方法,必須加@Override注解。 反例:getObject()與get0bject()的問題。一個是字母的O,一個是數(shù)字的0,加@Override可以準確判斷是否覆蓋成功。另外,如果在抽象類中對方法簽名進行修改,其實現(xiàn)類會馬上編譯報錯。 【強制】相同參數(shù)類型,相同業(yè)務(wù)含義,才可以使用Java的可變參數(shù),避免使用Object。 說明:可變參數(shù)必須放置在參數(shù)列表的最后。(提倡同學們盡量不用可變參數(shù)編程) 正例:public User getUsers(String type, Integer… ids); 【強制】對外暴露的接口簽名,原則上不允許修改方法簽名,避免對接口調(diào)用方產(chǎn)生影響。接口過時必須加@Deprecated注解,并清晰地說明采用的新接口或者新服務(wù)是什么。 【強制】不能使用過時的類或方法。 說明:java.net.URLDecoder 中的方法decode(String encodeStr) 這個方法已經(jīng)過時,應(yīng)該使用雙參數(shù)decode(String source, String encode)。接口提供方既然明確是過時接口,那么有義務(wù)同時提供新的接口;作為調(diào)用方來說,有義務(wù)去考證過時方法的新實現(xiàn)是什么。 【強制】Object的equals方法容易拋空指針異常,應(yīng)使用常量或確定有值的對象來調(diào)用equals。 正例: “test”.equals(object); 反例: object.equals(“test”); 說明:推薦使用java.util.Objects#equals (JDK7引入的工具類)【強制】所有的相同類型的包裝類對象之間值的比較,全部使用equals方法比較。 說明:對于Integer var=?在-128至127之間的賦值,Integer對象是在IntegerCache.cache產(chǎn)生,會復(fù)用已有對象,這個區(qū)間內(nèi)的Integer值可以直接使用==進行判斷,但是這個區(qū)間之外的所有數(shù)據(jù),都會在堆上產(chǎn)生,并不會復(fù)用已有對象,這是一個大坑,推薦使用equals方法進行判斷。 【強制】關(guān)于基本數(shù)據(jù)類型與包裝數(shù)據(jù)類型的使用標準如下: 1) 所有的POJO類屬性必須使用包裝數(shù)據(jù)類型。 2) RPC方法的返回值和參數(shù)必須使用包裝數(shù)據(jù)類型。 3) 所有的局部變量推薦使用基本數(shù)據(jù)類型。 說明:POJO類屬性沒有初值是提醒使用者在需要使用時,必須自己顯式地進行賦值,任何NPE問題,或者入庫檢查,都由使用者來保證。 正例:數(shù)據(jù)庫的查詢結(jié)果可能是null,因為自動拆箱,用基本數(shù)據(jù)類型接收有NPE風險。 反例:某業(yè)務(wù)的交易報表上顯示成交總額漲跌情況,即正負x%,x為基本數(shù)據(jù)類型,調(diào)用的RPC服務(wù),調(diào)用不成功時,返回的是默認值,頁面顯示:0%,這是不合理的,應(yīng)該顯示成中劃線-。所以包裝數(shù)據(jù)類型的null值,能夠表示額外的信息,如:遠程調(diào)用失敗,異常退出。 【強制】定義DO/DTO/VO等POJO類時,不要設(shè)定任何屬性默認值。 反例:某業(yè)務(wù)的DO的gmtCreate默認值為new Date();但是這個屬性在數(shù)據(jù)提取時并沒有置入具體值,在更新其它字段時又附帶更新了此字段,導(dǎo)致創(chuàng)建時間被修改成當前時間。 10.【強制】序列化類新增屬性時,請不要修改serialVersionUID字段,避免反序列失敗;如果完全不兼容升級,避免反序列化混亂,那么請修改serialVersionUID值。 說明:注意serialVersionUID不一致會拋出序列化運行時異常。 11.【強制】構(gòu)造方法里面禁止加入任何業(yè)務(wù)邏輯,如果有初始化邏輯,請放在init方法中。 12.【強制】POJO類必須寫toString方法。使用工具類source> generate toString時,如果繼承了另一個POJO類,注意在前面加一下super.toString。 說明:在方法執(zhí)行拋出異常時,可以直接調(diào)用POJO的toString()方法打印其屬性值,便于排查問題。 【推薦】使用索引訪問用String的split方法得到的數(shù)組時,需做最后一個分隔符后有無內(nèi)容的檢查,否則會有拋IndexOutOfBoundsException的風險。 說明: String str = “a,b,c,,”; String[] ary = str.split(“,”); //預(yù)期大于3,結(jié)果是3 System.out.println(ary.length); 14.【推薦】當一個類有多個構(gòu)造方法,或者多個同名方法,這些方法應(yīng)該按順序放置在一起,便于閱讀。 15.【推薦】 類內(nèi)方法定義順序依次是:公有方法或保護方法 > 私有方法 > getter/setter方法。 說明:公有方法是類的調(diào)用者和維護者最關(guān)心的方法,首屏展示最好;保護方法雖然只是子類關(guān)心,也可能是“模板設(shè)計模式”下的核心方法;而私有方法外部一般不需要特別關(guān)心,是一個黑盒實現(xiàn);因為方法信息價值較低,所有Service和DAO的getter/setter方法放在類體最后。 【推薦】setter方法中,參數(shù)名稱與類成員變量名稱一致,this.成員名=參數(shù)名。在getter/setter方法中,盡量不要增加業(yè)務(wù)邏輯,增加排查問題難度。 反例: public Integer getData(){ if(true) { return data + 100; } else { return data - 100; } }【推薦】循環(huán)體內(nèi),字符串的聯(lián)接方式,使用StringBuilder的append方法進行擴展。 說明:反編譯出的字節(jié)碼文件顯示每次循環(huán)都會new出一個StringBuilder對象,然后進行append操作,最后通過toString方法返回String對象,造成內(nèi)存資源浪費。 18.【推薦】final可提高程序響應(yīng)效率,聲明成final的情況: 1) 不需要重新賦值的變量,包括類屬性、局部變量。 2) 對象參數(shù)前加final,表示不允許修改引用的指向。 3) 類方法確定不允許被重寫。 19.【推薦】慎用Object的clone方法來拷貝對象。 說明:對象的clone方法默認是淺拷貝,若想實現(xiàn)深拷貝需要重寫clone方法實現(xiàn)屬性對象的拷貝。 20.【推薦】類成員與方法訪問控制從嚴: 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ù)、變量,嚴控訪問范圍。過寬泛的訪問范圍,不利于模塊解耦。思考:如果是一個private的方法,想刪除就刪除,可是一個public的Service方法,或者一個public的成員變量,刪除一下,不得手心冒點汗嗎?變量像自己的小孩,盡量在自己的視線內(nèi),變量作用域太大,如果無限制的到處跑,那么你會擔心的。 未完待續(xù)。。。。新聞熱點
疑難解答