編程規(guī)約
命名規(guī)范
變量命名不使用拼音镜撩。
領(lǐng)域模型相關(guān)命名使用全大寫。
UserDo
,UserDTO
常量名使用全大寫宜鸯,下劃線分開遮怜,盡量表達清除。
MAX_STOCK_COUNT
抽象類以Abstract或者Base開頭即碗。
BaseDAO
異常類名以Exception結(jié)尾陌凳。
測試類以它要測試的類的名稱開始,Test結(jié)尾初橘。
UserServiceTest
POJO中充岛,布爾類型變量名不要加is,某些框架會引起序列化錯誤夜只。
包名統(tǒng)一小寫蒜魄、單數(shù),類名如Utils可以復(fù)數(shù)。
接口方法不加修飾符號峦阁。
將設(shè)計模式體現(xiàn)在類名中
OrderFactory
,LoginProxy
,ResourceObserver
接口和實現(xiàn)類的命名規(guī)則:
- 對于Service和DAO耘成,暴露接口驹闰,內(nèi)部實現(xiàn)類使用Impl后綴撒会。
- 對于形容能力的接口,取對應(yīng)名詞作為實現(xiàn)類屹培。
AbstractTranslator
實現(xiàn)Translatable
枚舉類帶上Enum后綴怔檩,成員名稱大寫薛训。
Service/DAO層方法命名規(guī)約。
- 獲取單個對象的方法用get做前綴闸英。
- 獲取多個對象的方法法用list做前綴介袜。
- 獲取統(tǒng)計值方法用count做前綴。
- 插入的方法用save或insert做前綴沛豌。
- 刪除的方法用remove或delete做前綴赃额。
- 修改的方法用update做前綴。
領(lǐng)域模型命名規(guī)約
- 數(shù)據(jù)對象:xxxDO芍锦,xxx為表名飞盆。
- 數(shù)據(jù)傳輸對象:xxxDTO,xxx為業(yè)務(wù)領(lǐng)域相關(guān)名稱孽水。
- 展示對象:xxxVO城看,xxx一般為網(wǎng)頁名稱。
- POJP是DO/DTO/BO/VO的統(tǒng)稱
常量定義
- 不允許出現(xiàn)魔法值(即未經(jīng)定義的常量)直接出現(xiàn)在代碼中炼鞠。
- 常量應(yīng)用分層
- 跨應(yīng)用共享常量:放置在二方庫中。
- 應(yīng)用內(nèi)共享常量:放置在一方庫的modules的constant目錄下朝扼。
- 子工程內(nèi)部共享常量:在當(dāng)前子工程的constant目錄下霎肯。
- 包內(nèi)共享常量:放在包內(nèi)單獨的constant目錄下。
- 類內(nèi)共享常量:類內(nèi)部private static final肠仪。
3.如果變量值僅在一個范圍內(nèi)變化用Enum類备典。如果帶有名稱之外的延伸屬性提佣,必須使用Enum類
//正例:
public DayEnum{MONDAY(1),TUESDAY(2),WEDNESDAY(3),THURSDAY(4),FRIDAY(5),SATURDAY(6),SUNDAY(7);}
格式規(guī)約
- 大括號使用約定:
//正例
public static void main(String[] args) {
// 縮進 4 個空格
String say = "hello";
// 運算符的左右必須有一個空格
int flag = 0;
// 關(guān)鍵詞 if 與括號之間必須有一個空格,括號內(nèi)的 f 與左括號潮针, 0 與右括號不需要空格
if (flag == 0) {
System.out.println(say);
}
// 左大括號前加空格且不換行倚喂;左大括號后換行
if (flag == 1) {
System.out.println("world");
// 右大括號前換行,右大括號后有 else焦读,不用換行
} else {
System.out.println("ok");
// 在右大括號后直接結(jié)束舱权,則必須換行
}
}
- 單行字符不超過120個宴倍,換行規(guī)則如下:
- 第二行縮進4個空格,第三行不再繼續(xù)縮進鸵贬。
- 運算符阔逼、方法調(diào)用符與下文一起換行。
- 逗號后換行涯保。
//正例
dataset.add("a", "b", "c")...
.add("a", "b", "c")...
"d");
- 逗號后必須要有一個空格周伦。
- IDE的text file encoding設(shè)置為UTF-8,換行符用Unix格式及志。
- 方法體內(nèi)不同的業(yè)務(wù)邏輯語句組之間插入一個空格寨腔。
OOP規(guī)約
- 避免使用對象來訪問靜態(tài)變量或方法,直接用類名迫卢。
BeanUtils.copyProperties(model)
- 覆蓋方法必須加
@Override
注解。 - 接口被調(diào)用時乾蛤,不能改動家卖,過時加
@Deprecated
注解。 - 不能使用過時的類或方法趴樱。
- 使用常量或確定有值的對象來調(diào)用
equals
酪捡,或使用Objects.equals(a,b)
方法。 - 所有包裝類對象之間值的比較全部使用
equals
方法航揉。 - 關(guān)于基本數(shù)據(jù)類型與包裝數(shù)據(jù)類型的使用標(biāo)準(zhǔn)如下:
- 所有的POJO類屬性必須使用包裝數(shù)據(jù)類型金刁。
Long id
,public Integer count()
- RPC方法的返回值和參數(shù)使用包裝數(shù)據(jù)類型尤蛮。
- 所有局部變量使用基本數(shù)據(jù)類型。
- POJO類不要設(shè)定任何屬性默認(rèn)值醇锚。
- 序列化類新增屬性時,不要修改
serialVersionUID
焊唬。 - 構(gòu)造方法禁止加入任何業(yè)務(wù)邏輯赶促,初始化邏輯放在init方法中。
- POJO類必須寫
toString
方法嗦哆,注意繼承類時調(diào)用super.toString()
婿滓。 - 類內(nèi)定義順序依次是:公有方法或保護方法 > 私有方法 >
getter
/setter
-
getter
/setter
方法中不要增加業(yè)務(wù)邏輯。 - 類成員與方法訪問控制從嚴(yán):
- 如果不允許外部通過
new
來創(chuàng)建對象橘券,構(gòu)造方法必須為private
秕铛。 - 工具類不允許有
public
或default
構(gòu)造方法但两。 - 類非
static
成員變量并且與子類共享,必須是protected
绽快。 - 類非
static
成員變量并且僅在本類使用紧阔,必須是private
。 - 類
static
成員變量僅在本類使用活孩,必須為private
- 若是
static
成員變量乖仇,必須考慮是否為final
乃沙。 - 類成員方法僅供類內(nèi)部調(diào)用,必須是
private
训裆。 - 類成員方法只對繼承類公開,那么限制為
protected
属百。
集合處理
- 關(guān)于
hashCode
和equals
的處理艺骂,遵循如下規(guī)則:
- 只要重寫
equals
,則必須重寫hashCode
。 - 如果需要用
Set
存儲的對象忧额,必須重寫兩個方法愧口。 - 如果自定義對象作為
Map
的鍵,必須重寫兩個方法托嚣。
- 集合轉(zhuǎn)數(shù)組使用集合的
toArray(T[] array)
厚骗,傳入類型相同领舰,大小相同的數(shù)組。
String[] strArray = new String[list.size()];
strArray = list.toArray(strArray);
- 使用工具類
Arrays.asList()
把數(shù)組轉(zhuǎn)換成集合時舍咖,不能使用修改集合的方法
說明:體現(xiàn)了適配器模式锉桑,只是轉(zhuǎn)換接口,后臺的數(shù)據(jù)仍是數(shù)組攻柠。 -
Comparator
要滿足如下三個條件杉武,不然Arrays.sort
或Collections.sort
會報異常轻抱。
- x,y的比較結(jié)果和y,x的比較結(jié)果相反。
- x>y,y>z,則x>z较店。
- x=y,則x,z比較結(jié)果和y,z比較結(jié)果相同。
- 使用
entrySet
遍歷Map
婚度。 - 高度注意
Map
類集合能不能存儲null
值的情況官卡,如下表格:
|集合類|Key|Value|Super|說明|
|---|
|Hashtable
|不允許null
|不允許null
|Dictionary
|線程安全|
|ConcurrentHashMap
|不允許null
|不允許null
|AbstractMap
|分段鎖技術(shù)|
|TreeMap
|不允許null
|允許null
|AbstractMap
|線程不安全|
|HashMap
|允許null
|允許null
|AbstractMap
|線程不安全| - 利用
Set
來去重元素寻咒。
并發(fā)處理
獲取單例對象需要保證線程安全,其中的方法也要保證饭寺。
說明:資源驅(qū)動類叫挟、工具類、單例工廠都需要注意創(chuàng)建線程或線程池時請指定有意義的線程名稱员凝,方便出錯時回溯绊序。
public class TimerTaskThread extends Thread {
public TimerTaskThread() {
super.setName("TimerTaskThread"); ...
}
線程資源必須通過線程池提供秽荞,不允許在應(yīng)用中自行顯式創(chuàng)建線程。
說明:使用線程池的好處是減少在創(chuàng)建和銷毀線程上所花的時間以及系統(tǒng)資源的開銷阶捆,解決資源不足的問題钦听。如果不使用線程池朴上,有可能造成系統(tǒng)創(chuàng)建大量同類線程而導(dǎo)致消耗完內(nèi)存或者“過度切換”的問題。線程池不允許使用
Executors
去創(chuàng)建叼架,而是通過ThreadPoolExecutor
的方式,以更明確線程池運行規(guī)則扮饶。SimpleDateFormat
是線程不安全的類乍构,不要定義為static
,或使用DateUtils
工具類
private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue(){
return new SimpleDateFormat("yyyy-MM-dd");
}
}
高并發(fā)時岂丘,同步調(diào)用應(yīng)該去考量鎖的性能損耗元潘。無鎖數(shù)據(jù)結(jié)構(gòu)>鎖區(qū)塊>方法鎖>對象鎖>類鎖
對多個資源君仆、數(shù)據(jù)庫表牲距、對象同時加鎖時牍鞠,需要保持一致的加鎖順序,避免死鎖萤晴。
并發(fā)修改同一記錄時胁后,避免更新丟失攀芯,需要加鎖。要么在應(yīng)用加鎖殖演,要么在緩存加鎖年鸳,要么在數(shù)據(jù)庫層使用樂觀鎖,使用version作為更新依據(jù)彼棍。