《Java從小白到大牛》之第14章 異常處理(上)

《Java從小白到大疟绦牛》紙質(zhì)版已經(jīng)上架了!=重病砰碴!


Java從小白到大牛書皮

很多事件并非總是按照人們自己設計意愿順利發(fā)展的,而是有能夠出現(xiàn)這樣那樣的異常情況板丽。例如:你計劃周末郊游呈枉,你的計劃會安排滿滿的,你計劃可能是這樣的:從家里出發(fā)→到達目的→游泳→燒烤→回家埃碱。但天有不測風云猖辫,當前你準備燒烤時候天降大雨,你只能終止郊游提前回家砚殿】性鳎“天降大雨”是一種異常情況,你的計劃應該考慮到這樣情況似炎,并且應該有處理這種異常的預案辛萍。

為增強程序的健壯性,計算機程序的編寫也需要考慮處理這些異常情況羡藐,Java語言提供了異常處理功能贩毕,本章介紹Java異常處理機制。

從一個問題開始

為了學習Java異常處理機制仆嗦,首先看看下面程序辉阶。

//HelloWorld.java文件

package com.a51work6;

public class HelloWorld {

public static void main(String[] args) {

int a = 0;

System.out.println(5 / a);

}

}

這個程序沒有編譯錯誤,但會發(fā)生如下的運行時錯誤:

Exception in thread "main" java.lang.ArithmeticException: / by zero

at com.a51work6.HelloWorld.main(HelloWorld.java:9)

在數(shù)學上除數(shù)不能為0瘩扼,所以程序運行時表達式(5 / a)會拋出ArithmeticException異常谆甜,ArithmeticException是數(shù)學計算異常,凡是發(fā)生數(shù)學計算錯誤都會拋出該異常邢隧。

程序運行過程中難免會發(fā)生異常店印,發(fā)生異常并不可怕,程序員應該考慮到有可能發(fā)生這些異常倒慧,編程時應該捕獲并進行處理異常按摘,不能讓程序發(fā)生終止,這就是健壯的程序纫谅。

異常類繼承層次

異常封裝成為類Exception炫贤,此外,還有Throwable和Error類付秕,異常類繼承層次如圖14-1所示兰珍。


圖14-1 Java異常類繼承層次

Throwable類 {#throwable}

從圖14-1可見,所有的異常類都直接或間接地繼承于java.lang.Throwable類询吴,在Throwable類有幾個非常重要的方法:

  • String getMessage():獲得發(fā)生異常的詳細消息掠河。
  • void printStackTrace():打印異常堆棧跟蹤信息亮元。
  • String toString():獲得異常對象的描述。

提示 堆棧跟蹤是方法調(diào)用過程的軌跡唠摹,它包含了程序執(zhí)行過程中方法調(diào)用的順序和所在源代碼行號爆捞。

為了介紹Throwable類的使用,下面修改14.1節(jié)的示例代碼如下:

//HelloWorld.java文件

package com.a51work6;

public class HelloWorld {

public static void main(String[] args) {

int a = 0;

int result = divide(5, a);

System.out.printf("divide(%d, %d) = %d", 5, a, result);

}

public static int divide(int number, int divisor) {

try {

return number / divisor;

} catch (Throwable throwable) { ①

System.out.println("getMessage() : " + throwable.getMessage()); ②

System.out.println("toString() : " + throwable.toString()); ③

System.out.println("printStackTrace()輸出信息如下:");

throwable.printStackTrace(); ④

}

return 0;

}

}

運行結(jié)果如下:

getMessage() : / by zero

toString() : java.lang.ArithmeticException: / by zero

printStackTrace()輸出信息如下:

java.lang.ArithmeticException: / by zero

at com.a51work6.HelloWorld.divide(HelloWorld.java:17)

at com.a51work6.HelloWorld.main(HelloWorld.java:10)

divide(5, 0) = 0

將可以發(fā)生異常的語句System.out.println(5 / a)放到try-catch代碼塊中勾拉,稱為捕獲異常煮甥,有關(guān)捕獲異常的相關(guān)知識會在下一節(jié)詳細介紹。在catch中有一個Throwable對象throwable藕赞,throwable對象是系統(tǒng)在程序發(fā)生異常時創(chuàng)建成肘,通過throwable對象可以調(diào)用Throwable中定義的方法。

代碼第②行是調(diào)用getMessage()方法獲得異常消息斧蜕,輸出結(jié)果是“/ by zero”双霍。代碼第③行是調(diào)用toString()方法獲得異常對象的描述,輸出結(jié)果是java.lang.ArithmeticException: / by zero批销。代碼第④行是調(diào)用printStackTrace()方法打印異常堆棧跟蹤信息店煞。

提示 堆棧跟蹤信息從下往上,是方法調(diào)用的順序风钻。首先JVM調(diào)用是com.a51work6.HelloWorld類的main方法顷蟀,接著在HelloWorld.java源代碼第10行調(diào)用com.a51work6.HelloWorld類的divide方法,在HelloWorld.java源代碼第17行發(fā)生了異常骡技,最后輸出的是異常信息鸣个。

Error和Exception {#error-exception}

從圖14-1可見,Throwable有兩個直接子類:Error和Exception布朦。

  1. Error

Error是程序無法恢復的嚴重錯誤囤萤,程序員根本無能為力,只能讓程序終止是趴。例如:JVM內(nèi)部錯誤涛舍、內(nèi)存溢出和資源耗盡等嚴重情況。

  1. Exception

Exception是程序可以恢復的異常唆途,它是程序員所能掌控的富雅。例如:除零異常、空指針訪問肛搬、網(wǎng)絡連接中斷和讀取不存在的文件等没佑。本章所討論的異常處理就是對Exception及其子類的異常處理。

受檢查異常和運行時異常 {#-0}

從圖14-1可見温赔,Exception類可以分為:受檢查異常和運行時異常蛤奢。

  1. 受檢查異常

如圖14-1所示,受檢查異常是除RuntimeException以外的異常類。它們的共同特點是:編譯器會檢查這類異常是否進行了處理啤贩,即要么捕獲(try-catch語句)待秃,要么不拋出(通過在方法后聲明throws),否則會發(fā)生編譯錯誤痹屹。它們種類很多锥余,前面遇到過的日期解析異常ParseException。

  1. 運行時異常

運行時異常是繼承RuntimeException類的直接或間接子類痢掠。運行時異常往往是程序員所犯錯誤導致的,健壯的程序不應該發(fā)生運行時異常嘲恍。它們的共同特點是:編譯器不檢查這類異常是否進行了處理足画,也就是對于這類異常不捕獲也不拋出,程序也可以編譯通過佃牛。由于沒有進行異常處理淹辞,一旦運行時異常發(fā)生就會導致程序的終止,這是用戶不希望看到的俘侠。由于14.2.1節(jié)除零示例的ArithmeticException異常屬于RuntimeException異常象缀,見圖14-1所示,可以不用加try-catch語句捕獲異常爷速。

提示 對于運行時異常通常不采用拋出或捕獲處理方式央星,而是應該提前預判,防止這種發(fā)生異常惫东,做到未雨綢繆莉给。例如14.2.1節(jié)除零示例,在進行除法運算之前應該判斷除數(shù)是非零的廉沮,修改示例代碼如下颓遏,從代碼可見提前預判這樣處理要比通過try-catch捕獲異常要友好的多。

//HelloWorld.java文件

package com.a51work6;

public class HelloWorld {

public static void main(String[] args) {

int a = 0;

int result = divide(5, a);

System.out.printf("divide(%d, %d) = %d", 5, a, result);

}

public static int divide(int number, int divisor) {

//判斷除數(shù)divisor非零滞时,防止運行時異常

if (divisor != 0) {

return number / divisor;

}

return 0;

}

}

除了圖14-1所示異常叁幢,還有很多異常,本書不能一一窮盡坪稽,隨著學習的深入會介紹一些常用的異常曼玩,其他異常讀者可以自己查詢API文檔。

捕獲異常

在學習本內(nèi)容之前窒百,你先考慮一下演训,在現(xiàn)實生活中是如何對待領(lǐng)導交給你的任務呢?當然無非是兩種:自己有能解決的自己處理贝咙;自己無力解決的反饋給領(lǐng)導样悟,讓領(lǐng)導自己處理。

那么對待受檢查異常亦是如此。當前方法有能力解決窟她,則捕獲異常進行處理陈症;沒有能力解決,則拋出給上層調(diào)用方法處理震糖。如果上層調(diào)用方法還無力解決录肯,則繼續(xù)拋給它的上層調(diào)用方法,異常就是這樣向上傳遞直到有方法處理它吊说,如果所有的方法都沒有處理該異常论咏,那么JVM會終止程序運行。

這一節(jié)先介紹一下捕獲異常颁井。

try-catch語句 {#try-catch}

捕獲異常是通過try-catch語句實現(xiàn)的厅贪,最基本try-catch語句語法如下:

try{

//可能會發(fā)生異常的語句

} catch(Throwable e){

//處理異常e

}
  1. try代碼塊

try代碼塊中應該包含執(zhí)行過程中可能會發(fā)生異常的語句。一條語句是否有可能發(fā)生異常雅宾,這要看語句中調(diào)用的方法养涮。例如日期格式化類DateFormat的日期解析方法parse(),該方法的完整定義如下:

public Date parse(String source) throws ParseException

方法后面的throws ParseException說明:當調(diào)用parse()方法時有可以能產(chǎn)生ParseException異常眉抬。

提示 靜態(tài)方法贯吓、實例方法和構(gòu)造方法都可以聲明拋出異常,凡是拋出異常的方法都可以通過try-catch進行捕獲蜀变,當然運行時異城男常可以不捕獲。一個方法聲明拋出什么樣的異常需要查詢API文檔库北。

  1. catch代碼塊

每個try代碼塊可以伴隨一個或多個catch代碼塊尊沸,用于處理try代碼塊中所可能發(fā)生的多種異常。catch(Throwable e)語句中的e是捕獲異常對象贤惯,e必須是Throwable的子類洼专,異常對象e的作用域在該catch代碼塊中。

下面看看一個try-catch示例:

//HelloWorld.java文件

package com.a51work6;

import java.text.DateFormat;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class HelloWorld {

public static void main(String[] args) {

Date date = readDate();

System.out.println("日期 = " + date);

}

// 解析日期

public static Date readDate() { ①

try {

String str = "2018-8-18"; //"201A-18-18"

DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

// 從字符串中解析日期

Date date = df.parse(str); ②

return date;

} catch (ParseException e) { ③

System.out.println("處理ParseException…");

e.printStackTrace(); ④

}

return null;

}

}

上述代碼第①行定義了一個靜態(tài)方法用來將字符串解析成日期孵构,但并非所有的字符串都是有效的日期字符串屁商,因此調(diào)用代碼第②行的解析方法parse()有可能發(fā)生ParseException異常,ParseException是受檢查異常颈墅,在本例中使用try-catch捕獲蜡镶。代碼第③行的e就是ParseException對象。代碼第④行e.printStackTrace()是打印異常堆棧跟蹤信息恤筛,本例中的"2018-8-18"字符串是有個有效的日期字符串官还,因此不會發(fā)生異常。如果將字符串改為無效的日期字符串毒坛,如"201A-18-18"望伦,則會打印信息林说。

處理ParseException

java.text.ParseException: Unparseable date: "201A-18-18"

日期 = null

at java.text.DateFormat.parse(Unknown Source)

at com.a51work6.HelloWorld.readDate(HelloWorld.java:24)

at com.a51work6.HelloWorld.main(HelloWorld.java:13)

提示 在捕獲到異常之后,通過e.printStackTrace()語句打印異常堆棧跟蹤信息屯伞,往往只是用于調(diào)試腿箩,給程序員提示信息。堆棧跟蹤信息對最終用戶是沒有意義的劣摇,本例中如果出現(xiàn)異常很有可能是用戶輸入的日期無效珠移,捕獲到異常之后給用戶彈出一個對話框,提示用戶輸入日期無效末融,請用戶重新輸入钧惧,用戶重新輸入后再重新調(diào)用上述方法。這才是捕獲異常之后的正確處理方案勾习。

多catch代碼塊 {#catch}

如果try代碼塊中有很多語句會發(fā)生異常浓瞪,而且發(fā)生的異常種類又很多。那么可以在try后面跟有多個catch代碼塊语卤。多catch代碼塊語法如下:

try{

//可能會發(fā)生異常的語句

} catch(Throwable e){

//處理異常e

} catch(Throwable e){

//處理異常e

} catch(Throwable e){

//處理異常e

}

在多個catch代碼情況下,當一個catch代碼塊捕獲到一個異常時酪刀,其他的catch代碼塊就不再進行匹配粹舵。

注意 當捕獲的多個異常類之間存在父子關(guān)系時,捕獲異常順序與catch代碼塊的順序有關(guān)骂倘。一般先捕獲子類眼滤,后捕獲父類,否則子類捕獲不到历涝。

示例代碼如下:

//HelloWorld.java文件

package com.a51work6;

……

public class HelloWorld {

public static void main(String[] args) {

Date date = readDate();

System.out.println("讀取的日期 = " + date);

}

public static Date readDate() {

FileInputStream readfile = null;

InputStreamReader ir = null;

BufferedReader in = null;

try {

readfile = new FileInputStream("readme.txt"); ①

ir = new InputStreamReader(readfile);

in = new BufferedReader(ir);

// 讀取文件中的一行數(shù)據(jù)

String str = in.readLine(); ②

if (str == null) {

return null;

}

DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

Date date = df.parse(str); ③

return date;

} catch (FileNotFoundException e) { ④

System.out.println("處理FileNotFoundException...");

e.printStackTrace();

} catch (IOException e) { ⑤

System.out.println("處理IOException...");

e.printStackTrace();

} catch (ParseException e) { ⑥

System.out.println("處理ParseException...");

e.printStackTrace();

}

return null;

}

}

上述代碼通過Java I/O(輸入輸出)流技術(shù)從文件readme.txt中讀取字符串诅需,然后解析成為日期。由于Java I/O技術(shù)還沒有介紹荧库,讀者先不要關(guān)注I/O技術(shù)細節(jié)堰塌,這考慮調(diào)用它們的方法會發(fā)生異常就可以了。

在try代碼塊中第①行代碼調(diào)用FileInputStream構(gòu)造方法可以會發(fā)生FileNotFoundException異常分衫。第②行代碼調(diào)用BufferedReader輸入流的readLine()方法可以會發(fā)生IOException異常场刑。從圖14-1可見FileNotFoundException異常是IOException異常的子類,應該先FileNotFoundException捕獲蚪战,見代碼第④行牵现;后捕獲IOException,見代碼第⑤行邀桑。

如果將FileNotFoundException和IOException捕獲順序調(diào)換瞎疼,代碼如下:

try{

//可能會發(fā)生異常的語句

} catch (IOException e) {

// IOException異常處理

} catch (FileNotFoundException e) {

// FileNotFoundException異常處理

}

那么第二個catch代碼塊永遠不會進入,F(xiàn)ileNotFoundException異常處理永遠不會執(zhí)行壁畸。

由于上述代碼第⑥行ParseException異常與IOException和FileNotFoundException異常沒有父子關(guān)系贼急,捕獲ParseException異常位置可以隨意放置茅茂。

try-catch語句嵌套 {#try-catch-0}

Java提供的try-catch語句嵌套是可以任意嵌套,修改14.3.2節(jié)示例代碼如下:

//HelloWorld.java文件

package com.a51work6;

… …

public class HelloWorld {

public static void main(String[] args) {

Date date = readDate();

System.out.println("讀取的日期 = " + date);

}

public static Date readDate() {

FileInputStream readfile = null;

InputStreamReader ir = null;

BufferedReader in = null;

try {

readfile = new FileInputStream("readme.txt");

ir = new InputStreamReader(readfile);

in = new BufferedReader(ir);

try { ①

String str = in.readLine(); ②

if (str == null) {

return null;

}

DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

Date date = df.parse(str); ③

return date;

} catch (ParseException e) {

System.out.println("處理ParseException...");

e.printStackTrace();

} ④

} catch (FileNotFoundException e) { ⑤

System.out.println("處理FileNotFoundException...");

e.printStackTrace();

} catch (IOException e) { ⑥

System.out.println("處理IOException...");

e.printStackTrace();

}

return null;

}

}

上述代碼第①~④行是捕獲ParseException異常try-catch語句竿裂,可見這個try-catch語句就是嵌套在捕獲IOException和FileNotFoundException異常的try-catch語句中玉吁。

程序執(zhí)行時內(nèi)層如果會發(fā)生異常,首先由內(nèi)層catch進行捕獲腻异,如果捕獲不到进副,則由外層catch捕獲。例如:代碼第②行的readLine()方法可能發(fā)生IOException異常悔常,該異常無法被內(nèi)層catch捕獲影斑,最后被代碼第⑥行的外層catch捕獲。

注意 try-catch不僅可以嵌套在try代碼塊中机打,還可以嵌套在catch代碼塊或finally代碼塊矫户,finally代碼塊后面會詳細介紹。try-catch嵌套會使程序流程變的復雜残邀,如果能用多catch捕獲的異常皆辽,盡量不要使用try-catch嵌套。特別對于初學者不要簡單地使用Eclipse的語法提示不加區(qū)分地添加try-catch嵌套芥挣,要梳理好程序的流程再考慮try-catch嵌套的必要性驱闷。

多重捕獲 {#-0}

多catch代碼塊客觀上提高了程序的健壯性,但是程序代碼量大大增加空免。如果有些異常雖然種類不同空另,但捕獲之后的處理是相同的,看如下代碼蹋砚。

try{

//可能會發(fā)生異常的語句

} catch (FileNotFoundException e) {

//調(diào)用方法methodA處理

} catch (IOException e) {

//調(diào)用方法methodA處理

} catch (ParseException e) {

//調(diào)用方法methodA處理

}

三個不同類型的異常扼菠,要求捕獲之后的處理都是調(diào)用methodA方法。是否可以把這些異常合并處理坝咐,Java 7推出了多重捕獲(multi-catch)技術(shù)循榆,可以幫助解決此類問題,上述代碼修改如下:

try{

//可能會發(fā)生異常的語句

} catch (IOException | ParseException e) {

//調(diào)用方法methodA處理

}

在catch中多重捕獲異常用“|”運算符連接起來墨坚。

注意 有的讀者會問什么不寫成FileNotFoundException | IOException | ParseException 呢冯痢?這是因為由于FileNotFoundException屬于IOException異常,IOException異晨蚨牛可以捕獲它的所有子類異常了浦楣。

配套視頻

http://www.zhijieketang.com/classroom/6/courses

配套源代碼

http://www.zhijieketang.com/group/5

與本書免費版對應的還有一個收費版本:

  1. 進入百度閱讀電子書

  2. 進入圖靈社區(qū)電子書

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市咪辱,隨后出現(xiàn)的幾起案子振劳,更是在濱河造成了極大的恐慌,老刑警劉巖油狂,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件历恐,死亡現(xiàn)場離奇詭異寸癌,居然都是意外死亡,警方通過查閱死者的電腦和手機弱贼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門蒸苇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吮旅,你說我怎么就攤上這事溪烤。” “怎么了庇勃?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵檬嘀,是天一觀的道長。 經(jīng)常有香客問我责嚷,道長鸳兽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任罕拂,我火速辦了婚禮揍异,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘爆班。我一直安慰自己衷掷,他們只是感情好,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布蛋济。 她就那樣靜靜地躺著棍鳖,像睡著了一般炮叶。 火紅的嫁衣襯著肌膚如雪碗旅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天镜悉,我揣著相機與錄音祟辟,去河邊找鬼。 笑死侣肄,一個胖子當著我的面吹牛旧困,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播稼锅,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼吼具,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了矩距?” 一聲冷哼從身側(cè)響起拗盒,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锥债,沒想到半個月后陡蝇,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痊臭,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年登夫,在試婚紗的時候發(fā)現(xiàn)自己被綠了广匙。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡恼策,死狀恐怖鸦致,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情戏蔑,我是刑警寧澤蹋凝,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布谐岁,位于F島的核電站感凤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏闻葵。R本人自食惡果不足惜情龄,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一迄汛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骤视,春花似錦鞍爱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至祷肯,卻和暖如春沉填,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背佑笋。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工翼闹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蒋纬。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓猎荠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蜀备。 傳聞我的和親對象是個殘疾皇子关摇,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

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

  • packagetestexcrpltiom; importjava.text.ParseException; im...
    猿學閱讀 1,469評論 0 2
  • 引言 在程序運行過程中(注意是運行階段,程序可以通過編譯)碾阁,如果JVM檢測出一個不可能執(zhí)行的操作输虱,就會出現(xiàn)運行時錯...
    Steven1997閱讀 2,435評論 1 6
  • 一、前言 ??只要寫過Java代碼瓷蛙,基本上都會遇到異常悼瓮,由于以前學習的不夠系統(tǒng)戈毒,所以趁現(xiàn)在有時間,再來重新回顧及梳...
    騎著烏龜去看海閱讀 748評論 0 2
  • 2017年秋横堡,一出好戲在永無島上演埋市。 馬玲老師的又一次到來,迎來了歡呼與活力命贴,以及——沸騰道宅。這學期...
    天凈樹梓閱讀 267評論 1 4
  • 最近不知道是什么原因污茵,我總會因為一些小事無故對身邊的人發(fā)脾氣。 因為和2歲的小外甥嬉戲玩耍葬项,他咬了我一口泞当,我突然就...
    oumiga_guan閱讀 1,342評論 0 2