編程規(guī)約

一冠摄、編程規(guī)約

(一)命名規(guī)約

1.【強(qiáng)制】所有編程相關(guān)命名均不能以下劃線或美元符號開始,也不能以下劃線或美元符號結(jié)束声登。

反例:_name / __name / $Object / name_ / name$ / Object$

2.【強(qiáng)制】所有編程相關(guān)的命名嚴(yán)禁使用拼音與英文混合的方式涵紊,更不允許直接使用中文的方式。

說明:正確的英文拼寫和語法可以讓閱讀者易于理解蛉签,避免歧義胡陪。注意沥寥,即使純拼音命名方式

也要避免采用。

反例:DaZhePromotion [打折] / getPingfenByName() [評分] / int變量= 3;

正例:ali / alibaba / taobao / cainiao / aliyun / youku / hangzhou等國際通用的

名稱柠座,可視為英文邑雅。

3.【強(qiáng)制】類名使用UpperCamelCase風(fēng)格,必須遵從駝峰形式妈经,但以下情形例外:(領(lǐng)域模型 的相關(guān)命名)DO / DTO / VO / DAO等淮野。

正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion

反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion

4.【強(qiáng)制】方法名、參數(shù)名吹泡、成員變量骤星、局部變量都統(tǒng)一使用lowerCamelCase風(fēng)格,必須遵從

駝峰形式爆哑。

正例:localValue / getHttpMessage() / inputUserId

5.【強(qiáng)制】常量命名全部大寫洞难,單詞間用下劃線隔開,力求語義表達(dá)完整清楚揭朝,不要嫌名字長队贱。

正例:MAX_STOCK_COUNT

反例:MAX_COUNT

6.【強(qiáng)制】抽象類命名使用Abstract或Base開頭;異常類命名使用Exception結(jié)尾潭袱;測試類命 名以它要測試的類的名稱開始柱嫌,以Test結(jié)尾。

阿里巴巴JAVA開發(fā)手冊

2 / 32

7.【強(qiáng)制】中括號是數(shù)組類型的一部分屯换,數(shù)組定義如下:String[] args;反例:請勿使用String args[]的方式來定義

8.【強(qiáng)制】POJO類中的任何布爾類型的變量慎式,都不要加is,否則部分框架解析會引起序列化錯

誤趟径。

反例:定義為基本數(shù)據(jù)類型boolean isSuccess瘪吏;的屬性,它的方法也是isSuccess()蜗巧,RPC

框架在反向解析的時候掌眠,“以為”對應(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.mpp.util鸥跟、類名為MessageUtils(此規(guī)則參考spring

的框架結(jié)構(gòu))

10.【強(qiáng)制】杜絕完全不規(guī)范的縮寫,避免望文不知義。

反例:<某業(yè)務(wù)代碼>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.【推薦】接口類中的方法和屬性不要加任何修飾符號(public也不要加)角虫,保持代碼的簡潔

性,并加上有效的javadoc注釋委造。盡量不要在接口里定義變量上遥,如果一定要定義變量,肯定是

與接口方法相關(guān)争涌,并且是整個應(yīng)用的基礎(chǔ)常量粉楚。

正例:接口方法簽名:void f();

接口基礎(chǔ)常量表示:String COMPANY = "alibaba";

反例:接口方法定義: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接口继蜡。

阿里巴巴JAVA開發(fā)手冊

3 / 32

2)【推薦】 如果是形容能力的接口名稱回俐,取對應(yīng)的形容詞做接口名(通常是–able的形

式)。

正例:AbstractTranslator實(shí)現(xiàn)Translatable稀并。

14.【參考】枚舉類名建議帶上Enum后綴仅颇,枚舉成員名稱需要全大寫,單詞間用下劃線隔開碘举。

說明:枚舉其實(shí)就是特殊的常量類忘瓦,且構(gòu)造方法被默認(rèn)強(qiáng)制是私有。

正例:枚舉名字:DealStatusEnum引颈;成員名稱:SUCCESS / UNKOWN_REASON耕皮。

15.【參考】各層命名規(guī)約:

A) Service/DAO層方法命名規(guī)約

1) 獲取單個對象的方法用get做前綴。

2) 獲取多個對象的方法用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)制】不允許出現(xiàn)任何魔法值(即未經(jīng)定義的常量)直接出現(xiàn)在代碼中。

反例:String key="Id#taobao_"+tradeId蓬痒;

cache.put(key, value);

2.【強(qiáng)制】long或者Long初始賦值時,必須使用大寫的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下剑辫。

說明:大而全的常量類干旧,非得ctrl+f才定位到修改的常量,不利于理解妹蔽,也不利于維護(hù)椎眯。

阿里巴巴JAVA開發(fā)手冊

4 / 32

4.【推薦】常量的復(fù)用層次有五層:跨應(yīng)用共享常量、應(yīng)用內(nèi)共享常量胳岂、子工程內(nèi)共享常量编整、包

內(nèi)共享常量、類內(nèi)共享常量乳丰。

1) 跨應(yīng)用共享常量:放置在二方庫中闹击,通常是client.jar中的const目錄下。

2) 應(yīng)用內(nèi)共享常量:放置在一方庫的modules中的const目錄下成艘。

反例:易懂變量也要統(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)生線上問題。

3) 子工程內(nèi)部共享常量:即在當(dāng)前子工程的const目錄下秋冰。

4) 包內(nèi)共享常量:即在當(dāng)前包下單獨(dú)的const目錄下仲义。

5) 類內(nèi)共享常量:直接在類內(nèi)部private static final定義。

5.【推薦】如果變量值僅在一個范圍內(nèi)變化用Enum類。如果還帶有名稱之外的延伸屬性埃撵,必須 使用Enum類赵颅,下面正例中的數(shù)字就是延伸信息,表示星期幾暂刘。

正例:public Enum{ MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5),

SATURDAY(6), SUNDAY(7);}

(三)格式規(guī)約

1.【強(qiáng)制】大括號的使用約定饺谬。如果是大括號內(nèi)為空,則簡潔地寫成{}即可谣拣,不需要換行募寨;如果 是非空代碼塊則:

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縮進(jìn)爱谁,請?jiān)O(shè)置成1個tab為4個空格晒喷。 正例: (涉及1-5點(diǎn))

阿里巴巴JAVA開發(fā)手冊

5 / 32

public static void main(String args[]) { ?????//縮進(jìn)4個空格String say = "hello"; ?????//運(yùn)算符的左右必須有一個空格int flag = 0; ????//關(guān)鍵詞if與括號之間必須有一個空格,括號內(nèi)f與左括號访敌,1與右括號不需要空格if (flag == 0) { ?????????System.out.println(say); ?????} ??????????????//左大括號前加空格且不換行凉敲;左大括號后換行if (flag == 1) { ?????????System.out.println("world"); ?????//右大括號前換行,右大括號后有else寺旺,不用換行} else { ???????????System.out.println("ok"); ?????//右大括號做為結(jié)束爷抓,必須換行} ?} ?6.【強(qiáng)制】單行字符數(shù)限制不超過120個,超出需要換行阻塑,換行時蓝撇,遵循如下原則:1) 換行時相對上一行縮進(jìn)4個空格。

2) 運(yùn)算符與下文一起換行陈莽。

3) 方法調(diào)用的點(diǎn)符號與下文一起換行渤昌。

4) 在多個參數(shù)超長虽抄,逗號后進(jìn)行換行。

5) 在括號前不要換行独柑,見反例迈窟。

正例:

StringBuffer sb = new StringBuffer(); ?//超過120個字符的情況下,換行縮進(jìn)4個空格忌栅,并且方法前的點(diǎn)符號一起換行sb.append("zi").append("xin")….append("huang");

反例:

StringBuffer sb = new StringBuffer(); ?//超過120個字符的情況下车酣,不要在括號前換行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");

阿里巴巴JAVA開發(fā)手冊

6 / 32

8.【推薦】沒有必要增加若干空格來使某一行的字符與上一行的相應(yīng)字符對齊者春。

正例:

int a = 3; ?long b = 4L; ?float c = 5F; ?StringBuffer sb = new StringBuffer();說明:增加sb這個變量,如果需要對齊清女,則給a钱烟、b、c都要增加幾個空格嫡丙,在變量比較多的

情況下拴袭,是一種累贅的事情。

9.【強(qiáng)制】IDE的text file encoding設(shè)置為UTF-8; IDE中文件的換行符使用Unix格式曙博,不 要使用windows格式拥刻。

10.【推薦】方法體內(nèi)的執(zhí)行語句組、變量的定義語句組父泳、不同的業(yè)務(wù)邏輯之間或者不同的語義之

間插入一個空行般哼。相同業(yè)務(wù)邏輯和語義之間不需要插入空行。

說明:沒有必要插入多行空格進(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)類會馬上編

譯報(bào)錯座韵。

3.【強(qiáng)制】相同參數(shù)類型险绘,相同業(yè)務(wù)含義踢京,才可以使用Java的可變參數(shù),避免使用Object宦棺。 說明:可變參數(shù)必須放置在參數(shù)列表的最后瓣距。(提倡同學(xué)們盡量不用可變參數(shù)編程)

正例:public User getUsers(String type, Integer... ids); ?4.【強(qiáng)制】對外暴露的接口簽名,原則上不允許修改方法簽名代咸,避免對接口調(diào)用方產(chǎn)生影響蹈丸。接 口過時必須加@Deprecated注解,并清晰地說明采用的新接口或者新服務(wù)是什么呐芥。

5.【強(qiáng)制】不能使用過時的類或方法逻杖。 說明:java.net.URLDecoder中的方法decode(String encodeStr)這個方法已經(jīng)過時,應(yīng)該

使用雙參數(shù)decode(String source, String encode)思瘟。接口提供方既然明確是過時接口荸百,那

么有義務(wù)同時提供新的接口;作為調(diào)用方來說滨攻,有義務(wù)去考證過時方法的新實(shí)現(xiàn)是什么够话。

6.【強(qiáng)制】Object的equals方法容易拋空指針異常,應(yīng)使用常量或確定有值的對象來調(diào)用equals光绕。

正例:"test".equals(object);

阿里巴巴JAVA開發(fā)手冊

7 / 32

反例:object.equals("test");

說明:推薦使用java.util.Objects#equals(JDK7引入的工具類)

7.【強(qiáng)制】所有的相同類型的包裝類對象之間值的比較女嘲,全部使用equals方法比較。

說明:對于Integer var=?在-128至127之間的賦值诞帐,Integer對象是在IntegerCache.cache

產(chǎn)生欣尼,會復(fù)用已有對象,這個區(qū)間內(nèi)的Integer值可以直接使用==進(jìn)行判斷停蕉,但是這個區(qū)間之

外的所有數(shù)據(jù)愕鼓,都會在堆上產(chǎn)生,并不會復(fù)用已有對象谷徙,這是一個大坑拒啰,推薦使用equals方

法進(jìn)行判斷。

8.【強(qiáng)制】關(guān)于基本數(shù)據(jù)類型與包裝數(shù)據(jù)類型的使用標(biāo)準(zhǔn)如下:1) 所有的POJO類屬性必須使用包裝數(shù)據(jù)類型完慧。

2)RPC方法的返回值和參數(shù)必須使用包裝數(shù)據(jù)類型谋旦。

3) 所有的局部變量推薦使用基本數(shù)據(jù)類型。

說明:POJO類屬性沒有初值是提醒使用者在需要使用時屈尼,必須自己顯式地進(jìn)行賦值册着,任何

NPE問題,或者入庫檢查脾歧,都由使用者來保證甲捏。

正例:數(shù)據(jù)庫的查詢結(jié)果可能是null,因?yàn)樽詣硬鹣浔拗矗没緮?shù)據(jù)類型接收有NPE風(fēng)險(xiǎn)司顿。

反例:某業(yè)務(wù)的交易報(bào)表上顯示成交總額漲跌情況芒粹,即正負(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)值葵诈。 反例:某業(yè)務(wù)的DO的gmtCreate默認(rèn)值為new Date();但是這個屬性在數(shù)據(jù)提取時并沒有置

入具體值裸弦,在更新其它字段時又附帶更新了此字段祟同,導(dǎo)致創(chuàng)建時間被修改成當(dāng)前時間作喘。

10.【強(qiáng)制】序列化類新增屬性時,請不要修改serialVersionUID字段晕城,避免反序列失斉⑻埂;如果

完全不兼容升級砖顷,避免反序列化混亂贰锁,那么請修改serialVersionUID值。

說明:注意serialVersionUID不一致會拋出序列化運(yùn)行時異常滤蝠。

11.【強(qiáng)制】構(gòu)造方法里面禁止加入任何業(yè)務(wù)邏輯豌熄,如果有初始化邏輯,請放在init方法中物咳。

12.【強(qiáng)制】POJO類必須寫toString方法锣险。使用工具類source> generate toString時,如果繼

承了另一個POJO類览闰,注意在前面加一下super.toString芯肤。

說明:在方法執(zhí)行拋出異常時,可以直接調(diào)用POJO的toString()方法打印其屬性值压鉴,便于排

查問題崖咨。

13.【推薦】使用索引訪問用String的split方法得到的數(shù)組時,需做最后一個分隔符后有無內(nèi) 容的檢查油吭,否則會有拋IndexOutOfBoundsException的風(fēng)險(xiǎn)击蹲。

阿里巴巴JAVA開發(fā)手冊

8 / 32

說明:

String str = "a,b,c,,"; String[] ary = str.split(","); ?//預(yù)期大于3署拟,結(jié)果是3 System.out.println(ary.length); ?14.【推薦】當(dāng)一個類有多個構(gòu)造方法,或者多個同名方法歌豺,這些方法應(yīng)該按順序放置在一起芯丧,便

于閱讀。

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ù)邏輯禀崖,增加排查問題難度。

反例:

public Integer getData(){ ?????if(true) ?{ ?return data + 100; ?} else ?{ return data - 100; ?} ?} ?17.【推薦】循環(huán)體內(nèi)螟炫,字符串的聯(lián)接方式波附,使用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對象,造成內(nèi)存資源浪費(fèi)然评。

18.【推薦】final可提高程序響應(yīng)效率仅财,聲明成final的情況:

1) 不需要重新賦值的變量,包括類屬性碗淌、局部變量盏求。

2) 對象參數(shù)前加final,表示不允許修改引用的指向贯莺。

3) 類方法確定不允許被重寫风喇。

19.【推薦】慎用Object的clone方法來拷貝對象。

說明:對象的clone方法默認(rèn)是淺拷貝缕探,若想實(shí)現(xiàn)深拷貝需要重寫clone方法實(shí)現(xiàn)屬性對象的

拷貝魂莫。

阿里巴巴JAVA開發(fā)手冊

9 / 32

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)控訪問范圍。過寬泛的訪問范圍波丰,不利于模塊解耦壳坪。思

考:如果是一個private的方法,想刪除就刪除呀舔,可是一個public的Service方法弥虐,或者一

個public的成員變量扩灯,刪除一下媚赖,不得手心冒點(diǎn)汗嗎?變量像自己的小孩珠插,盡量在自己的視

線內(nèi)惧磺,變量作用域太大,如果無限制的到處跑捻撑,那么你會擔(dān)心的磨隘。

(五)集合處理

1.【強(qiáng)制】Map/Set的key為自定義對象時,必須重寫hashCode和equals顾患。 正例: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.【強(qiáng)制】在subList場景中魄梯,高度注意對原集合元素個數(shù)的修改,會導(dǎo)致子列表的遍歷宾符、增加酿秸、 刪除均產(chǎn)生ConcurrentModificationException異常。

4.【強(qiáng)制】使用集合轉(zhuǎn)數(shù)組的方法魏烫,必須使用集合的toArray(T[] array)辣苏,傳入的是類型完全 一樣的數(shù)組,大小就是list.size()哄褒。

反例:直接使用toArray無參方法存在問題考润,此方法返回值只能是Object[]類,若強(qiáng)轉(zhuǎn)其它

類型數(shù)組將出現(xiàn)ClassCastException錯誤读处。

正例:

List list = new ArrayList(2); ?????list.add("guan"); ?????list.add("bao"); ??????String[] array = new String[list.size()]; ?????array = list.toArray(array);

阿里巴巴JAVA開發(fā)手冊

10 / 32

說明:使用toArray帶參方法糊治,入?yún)⒎峙涞臄?shù)組空間不夠大時,toArray方法內(nèi)部將重新分配

內(nèi)存空間罚舱,并返回新數(shù)組地址井辜;如果數(shù)組元素大于實(shí)際所需,下標(biāo)為[ list.size() ]的數(shù)組

元素將被置為null管闷,其它數(shù)組元素保持原值粥脚,因此最好將方法入?yún)?shù)組大小定義與集合元素

個數(shù)一致。

5.【強(qiáng)制】使用工具類Arrays.asList()把數(shù)組轉(zhuǎn)換成集合時包个,不能使用其修改集合相關(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);

第一種情況:list.add("c");運(yùn)行時異常。

第二種情況:str[0]= "gujin";那么list.get(0)也會隨之修改熄驼。

6.【強(qiáng)制】泛型通配符來接收返回的數(shù)據(jù)像寒,此寫法的泛型集合不能使用add方法。

說明:蘋果裝箱后返回一個對象瓜贾,此對象就不能往里加任何水果诺祸,包括蘋

果。

7.【強(qiáng)制】不要在foreach循環(huán)里進(jìn)行元素的remove/add操作祭芦。remove元素請使用Iterator方式筷笨,如果并發(fā)操作,需要對Iterator對象加鎖。

反例:

List a = new ArrayList(); ?????a.add("1"); ?????a.add("2"); ?????for (String temp : a) { ?????????if("1".equals(temp)){ ?????????????a.remove(temp); ?????????} ?????}

說明:這個例子的執(zhí)行結(jié)果會出乎大家的意料奥秆,那么試一下把“1”換成“2”逊彭,會是同樣的結(jié)

果嗎?

正例:

Iterator it = a.iterator(); ?while(it.hasNext()){ ?????????????String temp = ?it.next(); ??????????????????????if(刪除元素的條件){ ?????????????????????????????it.remove(); ????????????????} ?????}

阿里巴巴JAVA開發(fā)手冊

11 / 32

8.【強(qiáng)制】在JDK7版本以上构订,Comparator要滿足自反性侮叮,傳遞性,對稱性悼瘾,不然Arrays.sort囊榜,

Collections.sort會報(bào)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() { ??????????@Override ?????????public int compare(Student o1, Student o2) { ?????????????return o1.getId() > o2.getId() ? 1 : -1; ?????????} ?????} ?9.【推薦】集合初始化時悟狱,盡量指定集合初始值大小。 說明:ArrayList盡量使用ArrayList(int initialCapacity)初始化堰氓。

10.【推薦】使用entrySet遍歷Map類集合KV挤渐,而不是keySet方式進(jìn)行遍歷。

說明:keySet其實(shí)是遍歷了2次双絮,一次是轉(zhuǎn)為Iterator對象浴麻,另一次是從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值的情況胚委,如下表格:

集合類Key Value Super說明

Hashtable不允許為null不允許為null Dictionary線程安全

ConcurrentHashMap不允許為null不允許為null AbstractMap線程局部安全

TreeMap不允許為null允許為null AbstractMap線程不安全

HashMap允許為null允許為null AbstractMap線程不安全

反例:很多同學(xué)認(rèn)為ConcurrentHashMap是可以置入null值。在批量翻譯場景中叉信,子線程分

發(fā)時亩冬,出現(xiàn)置入null值的情況,但主線程沒有捕獲到此異常,導(dǎo)致排查困難硅急。

12.【參考】合理利用好集合的有序性(sort)和穩(wěn)定性(order)覆享,避免集合的無序性(unsort)和不

穩(wěn)定性(unorder)帶來的負(fù)面影響。

阿里巴巴JAVA開發(fā)手冊

12 / 32

說明:穩(wěn)定性指集合每次遍歷的元素次序是一定的营袜。有序性是指遍歷的結(jié)果是按某種比較規(guī)則

依次排列的撒顿。如: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)制】線程資源必須通過線程池提供袱吆,不允許在應(yīng)用中自行顯式創(chuàng)建線程。

說明:使用線程池的好處是減少在創(chuàng)建和銷毀線程上所花的時間以及系統(tǒng)資源的開銷距淫,解決資

源不足的問題绞绒。如果不使用線程池,有可能造成系統(tǒng)創(chuàng)建大量同類線程而導(dǎo)致消耗完內(nèi)存或者

“過度切換”的問題榕暇。

3.【強(qiáng)制】SimpleDateFormat是線程不安全的類蓬衡,一般不要定義為static變量,如果定義為static彤枢,必須加鎖狰晚,或者使用DateUtils工具類。

正例:注意線程安全缴啡,使用DateUtils壁晒。亦推薦如下處理:

private static final ThreadLocal df = new ThreadLocal() { ???????@Override ???????protected DateFormat initialValue() { ???????????return new SimpleDateFormat("yyyy-MM-dd"); ???????} ???};說明:如果是JDK8的應(yīng)用,可以使用instant代替Date业栅,Localdatetime代替Calendar秒咐,

Datetimeformatter代替Simpledateformatter,官方給出的解釋:simple beautiful strong

immutable thread-safe碘裕。

4.【強(qiáng)制】高并發(fā)時携取,同步調(diào)用應(yīng)該去考量鎖的性能損耗。能用無鎖數(shù)據(jù)結(jié)構(gòu)帮孔,就不要用鎖雷滋;能 鎖區(qū)塊,就不要鎖整個方法體;能用對象鎖晤斩,就不要用類鎖焕檬。

5.【強(qiáng)制】對多個資源、數(shù)據(jù)庫表澳泵、對象同時加鎖時实愚,需要保持一致的加鎖順序,否則可能會造 成死鎖烹俗。

說明:線程一需要對表A爆侣、B、C依次全部加鎖后才可以進(jìn)行更新操作幢妄,那么線程二的加鎖順序

也必須是A兔仰、B、C蕉鸳,否則可能出現(xiàn)死鎖乎赴。

6.【強(qiáng)制】并發(fā)修改同一記錄時,避免更新丟失潮尝,要么在應(yīng)用層加鎖榕吼,要么在緩存加鎖,要么在

數(shù)據(jù)庫層使用樂觀鎖勉失,使用version作為更新依據(jù)羹蚣。

阿里巴巴JAVA開發(fā)手冊

13 / 32

說明:如果每次訪問沖突概率小于20%,推薦使用樂觀鎖乱凿,否則使用悲觀鎖顽素。樂觀鎖的重試次

數(shù)不得小于3次。

7.【強(qiáng)制】多線程并行處理定時任務(wù)時徒蟆,Timer運(yùn)行多個TimeTask時胁出,只要其中之一沒有捕獲 拋出的異常,其它任務(wù)便會自動終止運(yùn)行段审,使用ScheduledExecutorService則沒有這個問題全蝶。

8.【強(qiáng)制】線程池不允許使用Executors去創(chuàng)建,而是通過ThreadPoolExecutor的方式寺枉,這樣

的處理方式讓寫的同學(xué)更加明確線程池的運(yùn)行規(guī)則抑淫,規(guī)避資源耗盡的風(fēng)險(xiǎn)。

說明:Executors各個方法的弊端:

1)newFixedThreadPool和newSingleThreadExecutor:

主要問題是堆積的請求處理隊(duì)列可能會耗費(fèi)非常大的內(nèi)存型凳,甚至OOM丈冬。

2)newCachedThreadPool和newScheduledThreadPool:

主要問題是線程數(shù)最大數(shù)是Integer.MAX_VALUE,可能會創(chuàng)建數(shù)量非常多的線程甘畅,甚至OOM。

9.【強(qiáng)制】創(chuàng)建線程或線程池時請指定有意義的線程名稱,方便出錯時回溯疏唾。 正例:

public class TimerTaskThread extends Thread { ?????public TimerTaskThread(){ ?????????super.setName("TimerTaskThread");…} ?10.【推薦】使用CountDownLatch進(jìn)行異步轉(zhuǎn)同步操作蓄氧,每個線程退出前必須調(diào)用countDown方

法恕汇,線程執(zhí)行代碼注意catch異常咬扇,確保countDown方法可以執(zhí)行,避免主線程無法執(zhí)行至

countDown方法呻袭,直到超時才返回結(jié)果顿天。

說明:注意堂氯,子線程拋出異常堆棧,不能在主線程try-catch到牌废。

11.【推薦】避免Random實(shí)例被多線程使用咽白,雖然共享該實(shí)例是線程安全的,但會因競爭同一seed

導(dǎo)致的性能下降鸟缕。

說明:Random實(shí)例包括java.util.Random的實(shí)例或者M(jìn)ath.random()實(shí)例晶框。

正例:在JDK7之后,可以直接使用API ThreadLocalRandom懂从,在JDK7之前授段,可以做到每個線

程一個實(shí)例。

12.【推薦】通過雙重檢查鎖(double-checked locking)(在并發(fā)場景)實(shí)現(xiàn)延遲初始化的優(yōu)化 問題隱患(可參考The "Double-Checked Locking is Broken" Declaration),推薦問題解決方

案中較為簡單一種(適用于jdk5及以上版本)番甩,將目標(biāo)屬性聲明為volatile型(比如反例

中修改helper的屬性聲明為private volatile Helper helper = null;)侵贵;

反例:

class Foo { ??private Helper helper = null; ?public Helper getHelper() {

阿里巴巴JAVA開發(fā)手冊

14 / 32

if (helper == null) ??synchronized(this) { ?????if (helper == null) ????????helper = new Helper(); ???} ?????return helper; } ?// other functions and members...

} ?13.【參考】volatile解決多線程內(nèi)存不可見問題。對于一寫多讀缘薛,是可以解決變量同步問題窍育,

但是如果多寫,同樣無法解決線程安全問題掩宜。如果想取回count++數(shù)據(jù)蔫骂,使用如下類實(shí)現(xiàn):

AtomicInteger count = new AtomicInteger(); count.addAndGet(1); count++操作如果是

JDK8,推薦使用LongAdder對象牺汤,比AtomicLong性能更好(減少樂觀鎖的重試次數(shù))辽旋。

14.【參考】注意HashMap的擴(kuò)容死鏈,導(dǎo)致CPU飆升的問題檐迟。

15.【參考】ThreadLocal無法解決共享對象的更新問題补胚,ThreadLocal對象建議使用static修飾。

這個變量是針對一個線程內(nèi)所有操作共有的追迟,所以設(shè)置為靜態(tài)變量溶其,所有此類實(shí)例共享此靜態(tài)

變量,也就是說在類第一次被使用時裝載敦间,只分配一塊存儲空間瓶逃,所有此類的對象(只要是這

個線程內(nèi)定義的)都可以操控這個變量束铭。

(七)控制語句

1.【強(qiáng)制】在一個switch塊內(nèi),每個case要么通過break/return來終止厢绝,要么注釋說明程序 將繼續(xù)執(zhí)行到哪一個case為止契沫;在一個switch塊內(nèi),都必須包含一個default語句并且放在

最后昔汉,即使它什么代碼也沒有懈万。

2.【強(qiáng)制】在if/else/for/while/do語句中必須使用大括號,即使只有一行代碼靶病,避免使用下 面的形式:if (condition) statements;

3.【推薦】推薦盡量少用else会通,if-else的方式可以改寫成:

if(condition){…return obj; ???} ??//接著寫else的業(yè)務(wù)邏輯代碼;說明:如果使用要if-else if-else方式表達(dá)邏輯,【強(qiáng)制】請勿超過3層娄周,超過請使用狀態(tài)

設(shè)計(jì)模式涕侈。

4.【推薦】除常用方法(如getXxx/isXxx)等外,不要在條件判斷中執(zhí)行復(fù)雜的語句昆咽,以提高 可讀性驾凶。

正例:

//偽代碼如下InputStream stream = file.open(fileName, "w");

阿里巴巴JAVA開發(fā)手冊

15 / 32

if (stream != null) {…}反例:

if (file.open(fileName, "w") != null)) {…} ?5.【推薦】循環(huán)體中的語句要考量性能,以下操作盡量移至循環(huán)體外處理掷酗,如定義對象调违、變量、 獲取數(shù)據(jù)庫連接泻轰,進(jìn)行不必要的try-catch操作(這個try-catch是否可以移至循環(huán)體外)技肩。

6.【推薦】接口入?yún)⒈Wo(hù),這種場景常見的是用于做批量操作的接口浮声。

7.【參考】方法中需要進(jìn)行參數(shù)校驗(yàn)的場景:

1) 調(diào)用頻次低的方法虚婿。

2) 執(zhí)行時間開銷很大的方法,參數(shù)校驗(yàn)時間幾乎可以忽略不計(jì)泳挥,但如果因?yàn)閰?shù)錯誤導(dǎo)致

中間執(zhí)行回退然痊,或者錯誤,那得不償失屉符。

3) 需要極高穩(wěn)定性和可用性的方法剧浸。

4) 對外提供的開放接口,不管是RPC/API/HTTP接口矗钟。

8.【參考】方法中不需要參數(shù)校驗(yàn)的場景:

1) 極有可能被循環(huán)調(diào)用的方法唆香,不建議對參數(shù)進(jìn)行校驗(yàn)。但在方法說明里必須注明外部參

數(shù)檢查吨艇。

2) 底層的方法調(diào)用頻度都比較高躬它,一般不校驗(yàn)。畢竟是像純凈水過濾的最后一道东涡,參數(shù)錯

誤不太可能到底層才會暴露問題冯吓。一般DAO層與Service層都在同一個應(yīng)用中倘待,部署在同一臺

服務(wù)器中,所以DAO的參數(shù)校驗(yàn)桑谍,可以省略延柠。

3) 被聲明成private只會被自己代碼所調(diào)用的方法祸挪,如果能夠確定調(diào)用方法的代碼傳入?yún)?/p>

數(shù)已經(jīng)做過檢查或者肯定不會有問題锣披,此時可以不校驗(yàn)參數(shù)。

(八)注釋規(guī)約

1.【強(qiáng)制】類贿条、類屬性雹仿、類方法的注釋必須使用javadoc規(guī)范,使用/**內(nèi)容*/格式整以,不得使用//xxx方式胧辽。

說明:在IDE編輯窗口中,javadoc方式會提示相關(guān)注釋公黑,生成javadoc可以正確輸出相應(yīng)注

釋邑商;在IDE中,工程調(diào)用方法時凡蚜,不進(jìn)入方法即可懸浮提示方法人断、參數(shù)、返回值的意義朝蜘,提高

閱讀效率恶迈。

2.【強(qiáng)制】所有的抽象方法(包括接口中的方法)必須要用javadoc注釋、除了返回值谱醇、參數(shù)暇仲、

異常說明外,還必須指出該方法做什么事情副渴,實(shí)現(xiàn)什么功能奈附。

說明:如有實(shí)現(xiàn)和調(diào)用注意事項(xiàng),請一并說明煮剧。

阿里巴巴JAVA開發(fā)手冊

16 / 32

3.【強(qiáng)制】所有的類都必須添加創(chuàng)建者信息斥滤。

4.【強(qiáng)制】方法內(nèi)部單行注釋,在被注釋語句上方另起一行轿秧,使用//注釋中跌。方法內(nèi)部多行注釋使 用/* */注釋,注意與代碼對齊菇篡。

5.【強(qiáng)制】所有的枚舉類型字段必須要有注釋漩符,說明每個數(shù)據(jù)項(xiàng)的用途。

6.【推薦】與其“半吊子”英文來注釋驱还,不如用中文注釋把問題說清楚嗜暴。專有名詞凸克、關(guān)鍵字,保 持英文原文即可闷沥。

反例:“TCP連接超時”解釋成“傳輸控制協(xié)議連接超時”萎战,理解反而費(fèi)腦筋。

7.【推薦】代碼修改的同時舆逃,注釋也要進(jìn)行相應(yīng)的修改蚂维,尤其是參數(shù)、返回值路狮、異常虫啥、核心邏輯 等的修改。

說明:代碼與注釋更新不同步奄妨,就像路網(wǎng)與導(dǎo)航軟件更新不同步一樣涂籽,如果導(dǎo)航軟件嚴(yán)重滯后,

就失去了導(dǎo)航的意義砸抛。

8.【參考】注釋掉的代碼盡量要配合說明评雌,而不是簡單的注釋掉。 說明:代碼被注釋掉有兩種可能性:1)后續(xù)會恢復(fù)此段代碼邏輯直焙。2)永久不用景东。前者如果沒

有備注信息,難以知曉注釋動機(jī)箕般。后者建議直接刪掉(代碼倉庫保存了歷史代碼)耐薯。

9.【參考】對于注釋的要求:第一、能夠準(zhǔn)確反應(yīng)設(shè)計(jì)思想和代碼邏輯丝里;第二曲初、能夠描述業(yè)務(wù)含 義,使別的程序員能夠迅速了解到代碼背后的信息杯聚。完全沒有注釋的大段代碼對于閱讀者形同

天書臼婆,注釋是給自己看的,即使隔很長時間幌绍,也能清晰理解當(dāng)時的思路颁褂;注釋也是給繼任者看

的,使其能夠快速接替自己的工作傀广。

10.【參考】好的命名颁独、代碼結(jié)構(gòu)是自解釋的,注釋力求精簡準(zhǔn)確伪冰、表達(dá)到位誓酒。避免出現(xiàn)注釋的一

個極端:過多過濫的注釋,代碼的邏輯一旦修改贮聂,修改注釋是相當(dāng)大的負(fù)擔(dān)靠柑。

反例:

// put elephant into fridge ?put(elephant, fridge);方法名put寨辩,加上兩個有意義的變量名elephant和fridge,已經(jīng)說明了這是在干什么歼冰,

語義清晰的代碼不需要額外的注釋靡狞。

11.【參考】特殊注釋標(biāo)記,請注明標(biāo)記人與標(biāo)記時間隔嫡。注意及時處理這些標(biāo)記甸怕,通過標(biāo)記掃描,

經(jīng)常清理此類標(biāo)記畔勤。線上故障有時候就是來源于這些標(biāo)記處的代碼蕾各。

1) 待辦事宜(TODO):( 標(biāo)記人,標(biāo)記時間庆揪,[預(yù)計(jì)處理時間])

表示需要實(shí)現(xiàn),但目前還未實(shí)現(xiàn)的功能妨托。這實(shí)際上是一個javadoc的標(biāo)簽缸榛,目前的

javadoc還沒有實(shí)現(xiàn),但已經(jīng)被廣泛使用兰伤。只能應(yīng)用于類内颗,接口和方法(因?yàn)樗且粋€javadoc

標(biāo)簽)。

阿里巴巴JAVA開發(fā)手冊

17 / 32

2) 錯誤敦腔,不能工作(FIXME):(標(biāo)記人均澳,標(biāo)記時間,[預(yù)計(jì)處理時間])

在注釋中用FIXME標(biāo)記某代碼是錯誤的符衔,而且不能工作找前,需要及時糾正的情況。

(九)其它

1.【強(qiáng)制】在使用正則表達(dá)式時判族,利用好其預(yù)編譯功能躺盛,可以有效加快正則匹配速度。 說明:不要在方法體內(nèi)定義:Pattern pattern = Pattern.compile(規(guī)則);

2.【強(qiáng)制】避免用Apache Beanutils進(jìn)行屬性的copy形帮。 說明:Apache BeanUtils性能較差槽惫,可以使用其他方案比如Spring BeanUtils, Cglib

BeanCopier。

3.【強(qiáng)制】velocity調(diào)用POJO類的屬性時辩撑,建議直接使用屬性名取值即可界斜,模板引擎會自動按 規(guī)范調(diào)用POJO的getXxx(),如果是boolean基本數(shù)據(jù)類型變量(注意合冀,boolean命名不需要

加is前綴)各薇,會自動調(diào)用isXxx()方法。

說明:注意如果是Boolean包裝類對象水慨,優(yōu)先調(diào)用getXxx()的方法得糜。

4.【強(qiáng)制】后臺輸送給頁面的變量必須加$!{var}——中間的感嘆號敬扛。 說明:如果var=null或者不存在,那么${var}會直接顯示在頁面上朝抖。

5.【強(qiáng)制】注意Math.random()這個方法返回是double類型啥箭,注意取值范圍0≤x<1(能夠取 到零值,注意除零異常)治宣,如果想獲取整數(shù)類型的隨機(jī)數(shù)急侥,不要將x放大10的若干倍然后取

整,直接使用Random對象的nextInt或者nextLong方法侮邀。

6.【強(qiáng)制】獲取當(dāng)前毫秒數(shù):System.currentTimeMillis();而不是new Date().getTime();說明:如果想獲取更加精確的納秒級時間值坏怪,用System.nanoTime。在JDK8中绊茧,針對統(tǒng)計(jì)時

間等場景铝宵,推薦使用Instant類。

7.【推薦】盡量不要在vm中加入變量聲明华畏、邏輯運(yùn)算符鹏秋,更不要在vm模板中加入任何復(fù)雜的邏 輯。

8.【推薦】任何數(shù)據(jù)結(jié)構(gòu)的使用都應(yīng)限制大小亡笑。 說明:這點(diǎn)很難完全做到侣夷,但很多次的故障都是因?yàn)閿?shù)據(jù)結(jié)構(gòu)自增長,結(jié)果造成內(nèi)存被吃光仑乌。

9.【推薦】對于“明確停止使用的代碼和配置”百拓,如方法、變量晰甚、類衙传、配置文件、動態(tài)配置屬性 等要堅(jiān)決從程序中清理出去压汪,避免造成過多垃圾粪牲。清理這類垃圾代碼是技術(shù)氣場,不要有這樣

的觀念:“不做不錯止剖,多做多錯”腺阳。

阿里巴巴JAVA開發(fā)手冊

18 / 32

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市穿香,隨后出現(xiàn)的幾起案子亭引,更是在濱河造成了極大的恐慌,老刑警劉巖皮获,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焙蚓,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)购公,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門萌京,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宏浩,你說我怎么就攤上這事知残。” “怎么了比庄?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵求妹,是天一觀的道長。 經(jīng)常有香客問我佳窑,道長制恍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任神凑,我火速辦了婚禮净神,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘耙厚。我一直安慰自己强挫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布薛躬。 她就那樣靜靜地躺著,像睡著了一般呆细。 火紅的嫁衣襯著肌膚如雪型宝。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天絮爷,我揣著相機(jī)與錄音趴酣,去河邊找鬼。 笑死坑夯,一個胖子當(dāng)著我的面吹牛岖寞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播柜蜈,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼仗谆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了淑履?” 一聲冷哼從身側(cè)響起隶垮,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秘噪,沒想到半個月后狸吞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年蹋偏,在試婚紗的時候發(fā)現(xiàn)自己被綠了便斥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡威始,死狀恐怖枢纠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情字逗,我是刑警寧澤京郑,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站葫掉,受9級特大地震影響些举,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俭厚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一户魏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挪挤,春花似錦叼丑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至论寨,卻和暖如春星立,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背葬凳。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工绰垂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人火焰。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓劲装,卻偏偏與公主長得像,于是被迫代替她去往敵國和親昌简。 傳聞我的和親對象是個殘疾皇子占业,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容