国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

兩萬字詳解Java異常,面試再也不怕被問到!

共 21021字,需瀏覽 43分鐘

 ·

2021-12-17 11:35

Java異常簡介

Java異常是Java提供的一種識別及響應(yīng)錯誤的一致性機制。

Java異常機制可以使程序中異常處理代碼和正常業(yè)務(wù)代碼分離,保證程序代碼更加優(yōu)雅,并提高程序健壯性。在有效使用異常的情況下,異常能清晰的回答what, where, why這3個問題:異常類型回答了“什么”被拋出,異常堆棧跟蹤回答了“在哪”拋出,異常信息回答了“為什么”會拋出。

Java異常架構(gòu)

1. Throwable

Throwable 是 Java 語言中所有錯誤與異常的超類。

Throwable 包含兩個子類:Error(錯誤)和 Exception(異常),它們通常用于指示發(fā)生了異常情況。

Throwable 包含了其線程創(chuàng)建時線程執(zhí)行堆棧的快照,它提供了 printStackTrace() 等接口用于獲取堆棧跟蹤數(shù)據(jù)等信息。

2. Error(錯誤)

定義:Error 類及其子類。程序中無法處理的錯誤,表示運行應(yīng)用程序中出現(xiàn)了嚴重的錯誤。

特點:此類錯誤一般表示代碼運行時 JVM 出現(xiàn)問題。通常有 Virtual MachineError(虛擬機運行錯誤)、NoClassDefFoundError(類定義錯誤)等。比如 OutOfMemoryError:內(nèi)存不足錯誤;StackOverflowError:棧溢出錯誤。此類錯誤發(fā)生時,JVM 將終止線程。

這些錯誤是不受檢異常,非代碼性錯誤。因此,當此類錯誤發(fā)生時,應(yīng)用程序不應(yīng)該去處理此類錯誤。按照Java慣例,我們是不應(yīng)該實現(xiàn)任何新的Error子類的!

3. Exception(異常)

程序本身可以捕獲并且可以處理的異常。Exception 這種異常又分為兩類:運行時異常和編譯時異常。

運行時異常

定義:RuntimeException 類及其子類,表示 JVM 在運行期間可能出現(xiàn)的異常。

特點:Java 編譯器不會檢查它。也就是說,當程序中可能出現(xiàn)這類異常時,倘若既"沒有通過throws聲明拋出它",也"沒有用try-catch語句捕獲它",還是會編譯通過。比如NullPointerException空指針異常、ArrayIndexOutBoundException數(shù)組下標越界異常、ClassCastException類型轉(zhuǎn)換異常、ArithmeticExecption算術(shù)異常。

此類異常屬于不受檢異常,一般是由程序邏輯錯誤引起的,在程序中可以選擇捕獲處理,也可以不處理。雖然 Java 編譯器不會檢查運行時異常,但是我們也可以通過 throws 進行聲明拋出,也可以通過 try-catch 對它進行捕獲處理。如果產(chǎn)生運行時異常,則需要通過修改代碼來進行避免。例如,若會發(fā)生除數(shù)為零的情況,則需要通過代碼避免該情況的發(fā)生!

RuntimeException 異常會由 Java 虛擬機自動拋出并自動捕獲(就算我們沒寫異常捕獲語句運行時也會拋出錯誤!?。?,此類異常的出現(xiàn)絕大數(shù)情況是代碼本身有問題應(yīng)該從邏輯上去解決并改進代碼。

編譯時異常

定義: Exception 中除 RuntimeException 及其子類之外的異常。

特點: Java 編譯器會檢查它。如果程序中出現(xiàn)此類異常,比如 ClassNotFoundException(沒有找到指定的類異常),IOException(IO流異常),要么通過throws進行聲明拋出,要么通過try-catch進行捕獲處理,否則不能通過編譯。在程序中,通常不會自定義該類異常,而是直接使用系統(tǒng)提供的異常類。該異常我們必須手動在代碼里添加捕獲語句來處理該異常。

4. 受檢異常與非受檢異常

Java 的所有異??梢苑譃槭軝z異常(checked exception)和非受檢異常(unchecked exception)。

受檢異常

編譯器要求必須處理的異常。正確的程序在運行過程中,經(jīng)常容易出現(xiàn)的、符合預(yù)期的異常情況。一旦發(fā)生此類異常,就必須采用某種方式進行處理。除 RuntimeException 及其子類外,其他的 Exception 異常都屬于受檢異常。編譯器會檢查此類異常,也就是說當編譯器檢查到應(yīng)用中的某處可能會此類異常時,將會提示你處理本異?!词褂胻ry-catch捕獲,要么使用方法簽名中用 throws 關(guān)鍵字拋出,否則編譯不通過。

非受檢異常

編譯器不會進行檢查并且不要求必須處理的異常,也就說當程序中出現(xiàn)此類異常時,即使我們沒有try-catch捕獲它,也沒有使用throws拋出該異常,編譯也會正常通過。該類異常包括運行時異常(RuntimeException極其子類)和錯誤(Error)。

Java異常關(guān)鍵字

  • try – 用于監(jiān)聽。將要被監(jiān)聽的代碼(可能拋出異常的代碼)放在try語句塊之內(nèi),當try語句塊內(nèi)發(fā)生異常時,異常就被拋出。
  • catch – 用于捕獲異常。catch用來捕獲try語句塊中發(fā)生的異常。
  • finally – finally語句塊總是會被執(zhí)行。它主要用于回收在try塊里打開的物力資源(如數(shù)據(jù)庫連接、網(wǎng)絡(luò)連接和磁盤文件)。只有finally塊,執(zhí)行完成之后,才會回來執(zhí)行try或者catch塊中的return或者throw語句,如果finally中使用了return或者throw等終止方法的語句,則就不會跳回執(zhí)行,直接停止。
  • throw – 用于拋出異常。
  • throws – 用在方法簽名中,用于聲明該方法可能拋出的異常。

Java異常處理

Java 通過面向?qū)ο蟮姆椒ㄟM行異常處理,一旦方法拋出異常,系統(tǒng)自動根據(jù)該異常對象尋找合適異常處理器(Exception Handler)來處理該異常,把各種不同的異常進行分類,并提供了良好的接口。

在 Java 中,每個異常都是一個對象,它是 Throwable 類或其子類的實例。當一個方法出現(xiàn)異常后便拋出一個異常對象,該對象中包含有異常信息,調(diào)用這個對象的方法可以捕獲到這個異常并可以對其進行處理。Java 的異常處理是通過 5 個關(guān)鍵詞來實現(xiàn)的:try、catch、throw、throws 和 finally。

在Java應(yīng)用中,異常的處理機制分為聲明異常,拋出異常和捕獲異常。

聲明異常

通常,應(yīng)該捕獲那些知道如何處理的異常,將不知道如何處理的異常繼續(xù)傳遞下去。傳遞異??梢栽诜椒ê灻幨褂?throws 關(guān)鍵字聲明可能會拋出的異常。

注意

  • 非檢查異常(Error、RuntimeException 或它們的子類)不可使用 throws 關(guān)鍵字來聲明要拋出的異常。
  • 一個方法出現(xiàn)編譯時異常,就需要 try-catch/ throws 處理,否則會導(dǎo)致編譯錯誤。拋出異常

如果你覺得解決不了某些異常問題,且不需要調(diào)用者處理,那么你可以拋出異常。

throw關(guān)鍵字作用是在方法內(nèi)部拋出一個Throwable類型的異常。任何Java代碼都可以通過throw語句拋出異常。

捕獲異常

程序通常在運行之前不報錯,但是運行后可能會出現(xiàn)某些未知的錯誤,但是還不想直接拋出到上一級,那么就需要通過try…catch…的形式進行異常捕獲,之后根據(jù)不同的異常情況來進行相應(yīng)的處理。

如何選擇異常類型

可以根據(jù)下圖來選擇是捕獲異常,聲明異常還是拋出異常

常見異常處理方式

直接拋出異常

通常,應(yīng)該捕獲那些知道如何處理的異常,將不知道如何處理的異常繼續(xù)傳遞下去。傳遞異??梢栽诜椒ê灻幨褂?throws 關(guān)鍵字聲明可能會拋出的異常。

private?static?void?readFile(String?filePath)?throws?IOException?{
????File?file?=?new?File(filePath);
????String?result;
????BufferedReader?reader?=?new?BufferedReader(new?FileReader(file));
????while((result?=?reader.readLine())!=null)?{
????????System.out.println(result);
????}
????reader.close();
}

封裝異常再拋出

有時我們會從 catch 中拋出一個異常,目的是為了改變異常的類型。多用于在多系統(tǒng)集成時,當某個子系統(tǒng)故障,異常類型可能有多種,可以用統(tǒng)一的異常類型向外暴露,不需暴露太多內(nèi)部異常細節(jié)。

private?static?void?readFile(String?filePath)?throws?MyException?{????
????try?{
????????//?code
????}?catch?(IOException?e)?{
????????MyException?ex?=?new?MyException("read?file?failed.");
????????ex.initCause(e);
????????throw?ex;
????}
}

捕獲異常

在一個 try-catch 語句塊中可以捕獲多個異常類型,并對不同類型的異常做出不同的處理

private?static?void?readFile(String?filePath)?{
????try?{
????????//?code
????}?catch?(FileNotFoundException?e)?{
????????//?handle?FileNotFoundException
????}?catch?(IOException?e){
????????//?handle?IOException
????}
}

同一個 catch 也可以捕獲多種類型異常,用 | 隔開

private?static?void?readFile(String?filePath)?{
????try?{
????????//?code
????}?catch?(FileNotFoundException?|?UnknownHostException?e)?{
????????//?handle?FileNotFoundException?or?UnknownHostException
????}?catch?(IOException?e){
????????//?handle?IOException
????}
}

自定義異常

習(xí)慣上,定義一個異常類應(yīng)包含兩個構(gòu)造函數(shù),一個無參構(gòu)造函數(shù)和一個帶有詳細描述信息的構(gòu)造函數(shù)(Throwable 的 toString 方法會打印這些詳細信息,調(diào)試時很有用)

public?class?MyException?extends?Exception?{
????public?MyException(){?}
????public?MyException(String?msg){
????????super(msg);
????}
????//?...
}

try-catch-finally

當方法中發(fā)生異常,異常處之后的代碼不會再執(zhí)行,如果之前獲取了一些本地資源需要釋放,則需要在方法正常結(jié)束時和 catch 語句中都調(diào)用釋放本地資源的代碼,顯得代碼比較繁瑣,finally 語句可以解決這個問題。

private?static?void?readFile(String?filePath)?throws?MyException?{
????File?file?=?new?File(filePath);
????String?result;
????BufferedReader?reader?=?null;
????try?{
????????reader?=?new?BufferedReader(new?FileReader(file));
????????while((result?=?reader.readLine())!=null)?{
????????????System.out.println(result);
????????}
????}?catch?(IOException?e)?{
????????System.out.println("readFile?method?catch?block.");
????????MyException?ex?=?new?MyException("read?file?failed.");
????????ex.initCause(e);
????????throw?ex;
????}?finally?{
????????System.out.println("readFile?method?finally?block.");
????????if?(null?!=?reader)?{
????????????try?{
????????????????reader.close();
????????????}?catch?(IOException?e)?{
????????????????e.printStackTrace();
????????????}
????????}
????}
}

調(diào)用該方法時,讀取文件時若發(fā)生異常,代碼會進入 catch 代碼塊,之后進入 finally 代碼塊;若讀取文件時未發(fā)生異常,則會跳過 catch 代碼塊直接進入 finally 代碼塊。所以無論代碼中是否發(fā)生異常,fianlly 中的代碼都會執(zhí)行。

若 catch 代碼塊中包含 return 語句,finally 中的代碼還會執(zhí)行嗎?將以上代碼中的 catch 子句修改如下:

catch?(IOException?e)?{
????System.out.println("readFile?method?catch?block.");
????return;
}

調(diào)用 readFile 方法,觀察當 catch 子句中調(diào)用 return 語句時,finally 子句是否執(zhí)行

readFile?method?catch?block.
readFile?method?finally?block.

可見,即使 catch 中包含了 return 語句,finally 子句依然會執(zhí)行。若 finally 中也包含 return 語句,finally 中的 return 會覆蓋前面的 return.

try-with-resource

上面例子中,finally 中的 close 方法也可能拋出 IOException, 從而覆蓋了原始異常。JAVA 7 提供了更優(yōu)雅的方式來實現(xiàn)資源的自動釋放,自動釋放的資源需要是實現(xiàn)了 AutoCloseable 接口的類。

private??static?void?tryWithResourceTest(){
????try?(Scanner?scanner?=?new?Scanner(new?FileInputStream("c:/abc"),"UTF-8")){
????????//?code
????}?catch?(IOException?e){
????????//?handle?exception
????}
}

try 代碼塊退出時,會自動調(diào)用 scanner.close 方法,和把 scanner.close 方法放在 finally 代碼塊中不同的是,若 scanner.close 拋出異常,則會被抑制,拋出的仍然為原始異常。被抑制的異常會由 addSusppressed 方法添加到原來的異常,如果想要獲取被抑制的異常列表,可以調(diào)用 getSuppressed 方法來獲取。

Java異常常見面試題

1. Error 和 Exception 區(qū)別是什么?

Error 類型的錯誤通常為虛擬機相關(guān)錯誤,如系統(tǒng)崩潰,內(nèi)存不足,堆棧溢出等,編譯器不會對這類錯誤進行檢測,JAVA 應(yīng)用程序也不應(yīng)對這類錯誤進行捕獲,一旦這類錯誤發(fā)生,通常應(yīng)用程序會被終止,僅靠應(yīng)用程序本身無法恢復(fù);

Exception 類的錯誤是可以在應(yīng)用程序中進行捕獲并處理的,通常遇到這種錯誤,應(yīng)對其進行處理,使應(yīng)用程序可以繼續(xù)正常運行。

2. 運行時異常和一般異常(受檢異常)區(qū)別是什么?

運行時異常包括 RuntimeException 類及其子類,表示 JVM 在運行期間可能出現(xiàn)的異常。Java 編譯器不會檢查運行時異常。

受檢異常是Exception 中除 RuntimeException 及其子類之外的異常。Java 編譯器會檢查受檢異常。

RuntimeException異常和受檢異常之間的區(qū)別:是否強制要求調(diào)用者必須處理此異常,如果強制要求調(diào)用者必須進行處理,那么就使用受檢異常,否則就選擇非受檢異常(RuntimeException)。一般來講,如果沒有特殊的要求,我們建議使用RuntimeException異常。

3. JVM 是如何處理異常的?

在一個方法中如果發(fā)生異常,這個方法會創(chuàng)建一個異常對象,并轉(zhuǎn)交給 JVM,該異常對象包含異常名稱,異常描述以及異常發(fā)生時應(yīng)用程序的狀態(tài)。創(chuàng)建異常對象并轉(zhuǎn)交給 JVM 的過程稱為拋出異常??赡苡幸幌盗械姆椒ㄕ{(diào)用,最終才進入拋出異常的方法,這一系列方法調(diào)用的有序列表叫做調(diào)用棧。

JVM 會順著調(diào)用棧去查找看是否有可以處理異常的代碼,如果有,則調(diào)用異常處理代碼。當 JVM 發(fā)現(xiàn)可以處理異常的代碼時,會把發(fā)生的異常傳遞給它。如果 JVM 沒有找到可以處理該異常的代碼塊,JVM 就會將該異常轉(zhuǎn)交給默認的異常處理器(默認處理器為 JVM 的一部分),默認異常處理器打印出異常信息并終止應(yīng)用程序。

4. throw 和 throws 的區(qū)別是什么?

Java 中的異常處理除了包括捕獲異常和處理異常之外,還包括聲明異常和拋出異常,可以通過 throws 關(guān)鍵字在方法上聲明該方法要拋出的異常,或者在方法內(nèi)部通過 throw 拋出異常對象。

throws 關(guān)鍵字和 throw 關(guān)鍵字在使用上的幾點區(qū)別如下:

  • throw 關(guān)鍵字用在方法內(nèi)部,只能用于拋出一種異常,用來拋出方法或代碼塊中的異常,受查異常和非受查異常都可以被拋出。
  • throws 關(guān)鍵字用在方法聲明上,可以拋出多個異常,用來標識該方法可能拋出的異常列表。一個方法用 throws 標識了可能拋出的異常列表,調(diào)用該方法的方法中必須包含可處理異常的代碼,否則也要在方法簽名中用 throws 關(guān)鍵字聲明相應(yīng)的異常。

5. final、finally、finalize 有什么區(qū)別?

  • final可以修飾類、變量、方法,修飾類表示該類不能被繼承、修飾方法表示該方法不能被重寫、修飾變量表示該變量是一個常量不能被重新賦值。
  • finally一般作用在try-catch代碼塊中,在處理異常的時候,通常我們將一定要執(zhí)行的代碼方法finally代碼塊中,表示不管是否出現(xiàn)異常,該代碼塊都會執(zhí)行,一般用來存放一些關(guān)閉資源的代碼。
  • finalize是一個方法,屬于Object類的一個方法,而Object類是所有類的父類,Java 中允許使用 finalize()方法在垃圾收集器將對象從內(nèi)存中清除出去之前做必要的清理工作。

6. NoClassDefFoundError 和 ClassNotFoundException 區(qū)別?

NoClassDefFoundError 是一個 Error 類型的異常,是由 JVM 引起的,不應(yīng)該嘗試捕獲這個異常。

引起該異常的原因是 JVM 或 ClassLoader 嘗試加載某類時在內(nèi)存中找不到該類的定義,該動作發(fā)生在運行期間,即編譯時該類存在,但是在運行時卻找不到了,可能是變異后被刪除了等原因?qū)е拢?/p>

ClassNotFoundException 是一個受查異常,需要顯式地使用 try-catch 對其進行捕獲和處理,或在方法簽名中用 throws 關(guān)鍵字進行聲明。當使用 Class.forName, ClassLoader.loadClass 或 ClassLoader.findSystemClass 動態(tài)加載類到內(nèi)存的時候,通過傳入的類路徑參數(shù)沒有找到該類,就會拋出該異常;另一種拋出該異常的可能原因是某個類已經(jīng)由一個類加載器加載至內(nèi)存中,另一個加載器又嘗試去加載它。

7. try-catch-finally 中哪個部分可以省略?

答:catch 可以省略

原因

更為嚴格的說法其實是:try只適合處理運行時異常,try+catch適合處理運行時異常+普通異常。也就是說,如果你只用try去處理普通異常卻不加以catch處理,編譯是通不過的,因為編譯器硬性規(guī)定,普通異常如果選擇捕獲,則必須用catch顯示聲明以便進一步處理。而運行時異常在編譯時沒有如此規(guī)定,所以catch可以省略,你加上catch編譯器也覺得無可厚非。

理論上,編譯器看任何代碼都不順眼,都覺得可能有潛在的問題,所以你即使對所有代碼加上try,代碼在運行期時也只不過是在正常運行的基礎(chǔ)上加一層皮。但是你一旦對一段代碼加上try,就等于顯示地承諾編譯器,對這段代碼可能拋出的異常進行捕獲而非向上拋出處理。如果是普通異常,編譯器要求必須用catch捕獲以便進一步處理;如果運行時異常,捕獲然后丟棄并且+finally掃尾處理,或者加上catch捕獲以便進一步處理。

至于加上finally,則是在不管有沒捕獲異常,都要進行的“掃尾”處理。

8. try-catch-finally 中,如果 catch 中 return 了,finally 還會執(zhí)行嗎?

答:會執(zhí)行,在 return 前執(zhí)行。

注意:在 finally 中改變返回值的做法是不好的,因為如果存在 finally 代碼塊,try中的 return 語句不會立馬返回調(diào)用者,而是記錄下返回值待 finally 代碼塊執(zhí)行完畢之后再向調(diào)用者返回其值,然后如果在 finally 中修改了返回值,就會返回修改后的值。顯然,在 finally 中返回或者修改返回值會對程序造成很大的困擾,C#中直接用編譯錯誤的方式來阻止程序員干這種齷齪的事情,Java 中也可以通過提升編譯器的語法檢查級別來產(chǎn)生警告或錯誤。

代碼示例1:

public?static?int?getInt()?{
????int?a?=?10;
????try?{
????????System.out.println(a?/?0);
????????a?=?20;
????}?catch?(ArithmeticException?e)?{
????????a?=?30;
????????return?a;
????????/*
?????????* return a 在程序執(zhí)行到這一步的時候,這里不是return a 而是 return 30;這個返回路徑就形成了
?????????*?但是呢,它發(fā)現(xiàn)后面還有finally,所以繼續(xù)執(zhí)行finally的內(nèi)容,a=40
?????????*?再次回到以前的路徑,繼續(xù)走return?30,形成返回路徑之后,這里的a就不是a變量了,而是常量30
?????????*/

????}?finally?{
????????a?=?40;
????}
?return?a;
}

執(zhí)行結(jié)果:30

代碼示例2:

public?static?int?getInt()?{
????int?a?=?10;
????try?{
????????System.out.println(a?/?0);
????????a?=?20;
????}?catch?(ArithmeticException?e)?{
????????a?=?30;
????????return?a;
????}?finally?{
????????a?=?40;
????????//如果這樣,就又重新形成了一條返回路徑,由于只能通過1個return返回,所以這里直接返回40
????????return?a;?
????}

}

執(zhí)行結(jié)果:40

9. 類 ExampleA 繼承 Exception,類 ExampleB 繼承ExampleA。

有如下代碼片斷:

try?{
?throw?new?ExampleB("b")
}?catch(ExampleA?e){
?System.out.println("ExampleA");
}?catch(Exception?e){
?System.out.println("Exception");
}

請問執(zhí)行此段代碼的輸出是什么?

答:

輸出:ExampleA。(根據(jù)里氏代換原則[能使用父類型的地方一定能使用子類型],抓取 ExampleA 類型異常的 catch 塊能夠抓住 try 塊中拋出的 ExampleB 類型的異常)

面試題 - 說出下面代碼的運行結(jié)果。(此題的出處是《Java 編程思想》一書)

class?Annoyance?extends?Exception?{
}
class?Sneeze?extends?Annoyance?{
}
class?Human?{
?public?static?void?main(String[]?args)
?throws?Exception?
{
??try?{
???try?{
????throw?new?Sneeze();
???}?catch?(?Annoyance?a?)?{
????System.out.println("Caught?Annoyance");
????throw?a;
???}
??}?catch?(?Sneeze?s?)?{
???System.out.println("Caught?Sneeze");
???return?;
??}?finally?{
???System.out.println("Hello?World!");
??}
?}
}

結(jié)果

Caught?Annoyance
Caught?Sneeze
Hello?World!

10. 常見的 RuntimeException 有哪些?

  • ClassCastException(類轉(zhuǎn)換異常)
  • IndexOutOfBoundsException(數(shù)組越界)
  • NullPointerException(空指針)
  • ArrayStoreException(數(shù)據(jù)存儲異常,操作數(shù)組時類型不一致)
  • 還有IO操作的BufferOverflowException異常

11. Java常見異常有哪些

java.lang.IllegalAccessError:違法訪問錯誤。當一個應(yīng)用試圖訪問、修改某個類的域(Field)或者調(diào)用其方法,但是又違反域或方法的可見性聲明,則拋出該異常。

java.lang.InstantiationError:實例化錯誤。當一個應(yīng)用試圖通過Java的new操作符構(gòu)造一個抽象類或者接口時拋出該異常.

java.lang.OutOfMemoryError:內(nèi)存不足錯誤。當可用內(nèi)存不足以讓Java虛擬機分配給一個對象時拋出該錯誤。

java.lang.StackOverflowError:堆棧溢出錯誤。當一個應(yīng)用遞歸調(diào)用的層次太深而導(dǎo)致堆棧溢出或者陷入死循環(huán)時拋出該錯誤。

java.lang.ClassCastException:類造型異常。假設(shè)有類A和B(A不是B的父類或子類),O是A的實例,那么當強制將O構(gòu)造為類B的實例時拋出該異常。該異常經(jīng)常被稱為強制類型轉(zhuǎn)換異常。

java.lang.ClassNotFoundException:找不到類異常。當應(yīng)用試圖根據(jù)字符串形式的類名構(gòu)造類,而在遍歷CLASSPAH之后找不到對應(yīng)名稱的class文件時,拋出該異常。

java.lang.ArithmeticException:算術(shù)條件異常。譬如:整數(shù)除零等。

java.lang.ArrayIndexOutOfBoundsException:數(shù)組索引越界異常。當對數(shù)組的索引值為負數(shù)或大于等于數(shù)組大小時拋出。

java.lang.IndexOutOfBoundsException:索引越界異常。當訪問某個序列的索引值小于0或大于等于序列大小時,拋出該異常。

java.lang.InstantiationException:實例化異常。當試圖通過newInstance()方法創(chuàng)建某個類的實例,而該類是一個抽象類或接口時,拋出該異常。

java.lang.NoSuchFieldException:屬性不存在異常。當訪問某個類的不存在的屬性時拋出該異常。

java.lang.NoSuchMethodException:方法不存在異常。當訪問某個類的不存在的方法時拋出該異常。

java.lang.NullPointerException:空指針異常。當應(yīng)用試圖在要求使用對象的地方使用了null時,拋出該異常。譬如:調(diào)用null對象的實例方法、訪問null對象的屬性、計算null對象的長度、使用throw語句拋出null等等。

java.lang.NumberFormatException:數(shù)字格式異常。當試圖將一個String轉(zhuǎn)換為指定的數(shù)字類型,而該字符串確不滿足數(shù)字類型要求的格式時,拋出該異常。

java.lang.StringIndexOutOfBoundsException:字符串索引越界異常。當使用索引值訪問某個字符串中的字符,而該索引值小于0或大于等于序列大小時,拋出該異常。

Java異常處理最佳實踐

在 Java 中處理異常并不是一個簡單的事情。不僅僅初學(xué)者很難理解,即使一些有經(jīng)驗的開發(fā)者也需要花費很多時間來思考如何處理異常,包括需要處理哪些異常,怎樣處理等等。這也是絕大多數(shù)開發(fā)團隊都會制定一些規(guī)則來規(guī)范進行異常處理的原因。而團隊之間的這些規(guī)范往往是截然不同的。

本文給出幾個被很多團隊使用的異常處理最佳實踐。

1. 在 finally 塊中清理資源或者使用 try-with-resource 語句

當使用類似InputStream這種需要使用后關(guān)閉的資源時,一個常見的錯誤就是在try塊的最后關(guān)閉資源。

public?void?doNotCloseResourceInTry()?{
????FileInputStream?inputStream?=?null;
????try?{
????????File?file?=?new?File("./tmp.txt");
????????inputStream?=?new?FileInputStream(file);
????????//?use?the?inputStream?to?read?a?file
????????//?do?NOT?do?this
????????inputStream.close();
????}?catch?(FileNotFoundException?e)?{
????????log.error(e);
????}?catch?(IOException?e)?{
????????log.error(e);
????}
}

問題就是,只有沒有異常拋出的時候,這段代碼才可以正常工作。try 代碼塊內(nèi)代碼會正常執(zhí)行,并且資源可以正常關(guān)閉。但是,使用 try 代碼塊是有原因的,一般調(diào)用一個或多個可能拋出異常的方法,而且,你自己也可能會拋出一個異常,這意味著代碼可能不會執(zhí)行到 try 代碼塊的最后部分。結(jié)果就是,你并沒有關(guān)閉資源。

所以,你應(yīng)該把清理工作的代碼放到 finally 里去,或者使用 try-with-resource 特性。

1.1 使用 finally 代碼塊

與前面幾行 try 代碼塊不同,finally 代碼塊總是會被執(zhí)行。不管 try 代碼塊成功執(zhí)行之后還是你在 catch 代碼塊中處理完異常后都會執(zhí)行。因此,你可以確保你清理了所有打開的資源。

public?void?closeResourceInFinally()?{
????FileInputStream?inputStream?=?null;
????try?{
????????File?file?=?new?File("./tmp.txt");
????????inputStream?=?new?FileInputStream(file);
????????//?use?the?inputStream?to?read?a?file
????}?catch?(FileNotFoundException?e)?{
????????log.error(e);
????}?finally?{
????????if?(inputStream?!=?null)?{
????????????try?{
????????????????inputStream.close();
????????????}?catch?(IOException?e)?{
????????????????log.error(e);
????????????}
????????}
????}
}

1.2 Java 7 的 try-with-resource 語法

如果你的資源實現(xiàn)了 AutoCloseable 接口,你可以使用這個語法。大多數(shù)的 Java 標準資源都繼承了這個接口。當你在 try 子句中打開資源,資源會在 try 代碼塊執(zhí)行后或異常處理后自動關(guān)閉。

public?void?automaticallyCloseResource()?{
????File?file?=?new?File("./tmp.txt");
????try?(FileInputStream?inputStream?=?new?FileInputStream(file);)?{
????????//?use?the?inputStream?to?read?a?file
????}?catch?(FileNotFoundException?e)?{
????????log.error(e);
????}?catch?(IOException?e)?{
????????log.error(e);
????}
}

2. 優(yōu)先明確的異常

你拋出的異常越明確越好,永遠記住,你的同事或者幾個月之后的你,將會調(diào)用你的方法并且處理異常。

因此需要保證提供給他們盡可能多的信息。這樣你的 API 更容易被理解。你的方法的調(diào)用者能夠更好的處理異常并且避免額外的檢查。

因此,總是嘗試尋找最適合你的異常事件的類,例如,拋出一個 NumberFormatException 來替換一個 IllegalArgumentException 。避免拋出一個不明確的異常。

public?void?doNotDoThis()?throws?Exception?{
????...
}
public?void?doThis()?throws?NumberFormatException?{
????...
}

3. 對異常進行文檔說明

當在方法上聲明拋出異常時,也需要進行文檔說明。目的是為了給調(diào)用者提供盡可能多的信息,從而可以更好地避免或處理異常。

在 Javadoc 添加 @throws 聲明,并且描述拋出異常的場景。

public?void?doSomething(String?input)?throws?MyBusinessException?{
????...
}

4. 使用描述性消息拋出異常

在拋出異常時,需要盡可能精確地描述問題和相關(guān)信息,這樣無論是打印到日志中還是在監(jiān)控工具中,都能夠更容易被人閱讀,從而可以更好地定位具體錯誤信息、錯誤的嚴重程度等。

但這里并不是說要對錯誤信息長篇大論,因為本來 Exception 的類名就能夠反映錯誤的原因,因此只需要用一到兩句話描述即可。

如果拋出一個特定的異常,它的類名很可能已經(jīng)描述了這種錯誤。所以,你不需要提供很多額外的信息。一個很好的例子是 NumberFormatException 。當你以錯誤的格式提供 String 時,它將被 java.lang.Long 類的構(gòu)造函數(shù)拋出。

try?{
????new?Long("xyz");
}?catch?(NumberFormatException?e)?{
????log.error(e);
}

5. 優(yōu)先捕獲最具體的異常

大多數(shù) IDE 都可以幫助你實現(xiàn)這個最佳實踐。當你嘗試首先捕獲較不具體的異常時,它們會報告無法訪問的代碼塊。

但問題在于,只有匹配異常的第一個 catch 塊會被執(zhí)行。因此,如果首先捕獲 IllegalArgumentException ,則永遠不會到達應(yīng)該處理更具體的 NumberFormatException 的 catch 塊,因為它是 IllegalArgumentException 的子類。

總是優(yōu)先捕獲最具體的異常類,并將不太具體的 catch 塊添加到列表的末尾。

你可以在下面的代碼片斷中看到這樣一個 try-catch 語句的例子。第一個 catch 塊處理所有 NumberFormatException 異常,第二個處理所有非 NumberFormatException 異常的IllegalArgumentException 異常。

public?void?catchMostSpecificExceptionFirst()?{
????try?{
????????doSomething("A?message");
????}?catch?(NumberFormatException?e)?{
????????log.error(e);
????}?catch?(IllegalArgumentException?e)?{
????????log.error(e)
????}
}

6. 不要捕獲 Throwable 類

Throwable 是所有異常和錯誤的超類。你可以在 catch 子句中使用它,但是你永遠不應(yīng)該這樣做!

如果在 catch 子句中使用 Throwable ,它不僅會捕獲所有異常,也將捕獲所有的錯誤。JVM 拋出錯誤,指出不應(yīng)該由應(yīng)用程序處理的嚴重問題。典型的例子是 OutOfMemoryError 或者 StackOverflowError 。兩者都是由應(yīng)用程序控制之外的情況引起的,無法處理。

所以,最好不要捕獲 Throwable ,除非你確定自己處于一種特殊的情況下能夠處理錯誤。

public?void?doNotCatchThrowable()?{
????try?{
????????//?do?something
????}?catch?(Throwable?t)?{
????????//?don't?do?this!
????}
}

7. 不要忽略異常

很多時候,開發(fā)者很有自信不會拋出異常,因此寫了一個catch塊,但是沒有做任何處理或者記錄日志。

public?void?doNotIgnoreExceptions()?{
????try?{
????????//?do?something
????}?catch?(NumberFormatException?e)?{
????????//?this?will?never?happen
????}
}

但現(xiàn)實是經(jīng)常會出現(xiàn)無法預(yù)料的異常,或者無法確定這里的代碼未來是不是會改動(刪除了阻止異常拋出的代碼),而此時由于異常被捕獲,使得無法拿到足夠的錯誤信息來定位問題。

合理的做法是至少要記錄異常的信息。

public?void?logAnException()?{
????try?{
????????//?do?something
????}?catch?(NumberFormatException?e)?{
????????log.error("This?should?never?happen:?"?+?e);
????}
}

8. 不要記錄并拋出異常

這可能是本文中最常被忽略的最佳實踐??梢园l(fā)現(xiàn)很多代碼甚至類庫中都會有捕獲異常、記錄日志并再次拋出的邏輯。如下:

try?{
????new?Long("xyz");
}?catch?(NumberFormatException?e)?{
????log.error(e);
????throw?e;
}

這個處理邏輯看著是合理的。但這經(jīng)常會給同一個異常輸出多條日志。如下:

17:44:28,945?ERROR?TestExceptionHandling:65?-?java.lang.NumberFormatException:?For?input?string:?"xyz"
Exception?in?thread?"main"?java.lang.NumberFormatException:?For?input?string:?"xyz"
at?java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at?java.lang.Long.parseLong(Long.java:589)
at?java.lang.Long.(Long.java:965)
at?com.stackify.example.TestExceptionHandling.logAndThrowException(TestExceptionHandling.java:63)
at?com.stackify.example.TestExceptionHandling.main(TestExceptionHandling.java:58)

如上所示,后面的日志也沒有附加更有用的信息。如果想要提供更加有用的信息,那么可以將異常包裝為自定義異常。

public?void?wrapException(String?input)?throws?MyBusinessException?{
????try?{
????????//?do?something
????}?catch?(NumberFormatException?e)?{
????????throw?new?MyBusinessException("A?message?that?describes?the?error.",?e);
????}
}

因此,僅僅當想要處理異常時才去捕獲,否則只需要在方法簽名中聲明讓調(diào)用者去處理。

9. 包裝異常時不要拋棄原始的異常

捕獲標準異常并包裝為自定義異常是一個很常見的做法。這樣可以添加更為具體的異常信息并能夠做針對的異常處理。

在你這樣做時,請確保將原始異常設(shè)置為原因(注:參考下方代碼 NumberFormatException e 中的原始異常 e )。Exception 類提供了特殊的構(gòu)造函數(shù)方法,它接受一個 Throwable 作為參數(shù)。否則,你將會丟失堆棧跟蹤和原始異常的消息,這將會使分析導(dǎo)致異常的異常事件變得困難。

public?void?wrapException(String?input)?throws?MyBusinessException?{
????try?{
????????//?do?something
????}?catch?(NumberFormatException?e)?{
????????throw?new?MyBusinessException("A?message?that?describes?the?error.",?e);
????}
}

10. 不要使用異??刂瞥绦虻牧鞒?span style="display: none;">

不應(yīng)該使用異常控制應(yīng)用的執(zhí)行流程,例如,本應(yīng)該使用if語句進行條件判斷的情況下,你卻使用異常處理,這是非常不好的習(xí)慣,會嚴重影響應(yīng)用的性能。

11. 使用標準異常

如果使用內(nèi)建的異??梢越鉀Q問題,就不要定義自己的異常。Java API 提供了上百種針對不同情況的異常類型,在開發(fā)中首先盡可能使用 Java API 提供的異常,如果標準的異常不能滿足你的要求,這時候創(chuàng)建自己的定制異常。盡可能得使用標準異常有利于新加入的開發(fā)者看懂項目代碼。

12. 異常會影響性能

異常處理的性能成本非常高,每個 Java 程序員在開發(fā)時都應(yīng)牢記這句話。創(chuàng)建一個異常非常慢,拋出一個異常又會消耗1~5ms,當一個異常在應(yīng)用的多個層級之間傳遞時,會拖累整個應(yīng)用的性能。

僅在異常情況下使用異常;

  • 在可恢復(fù)的異常情況下使用異常;
  • 盡管使用異常有利于 Java 開發(fā),但是在應(yīng)用中最好不要捕獲太多的調(diào)用棧,因為在很多情況下都不需要打印調(diào)用棧就知道哪里出錯了。因此,異常消息應(yīng)該提供恰到好處的信息。

13. 總結(jié)

綜上所述,當你拋出或捕獲異常的時候,有很多不同的情況需要考慮,而且大部分事情都是為了改善代碼的可讀性或者 API 的可用性。

異常不僅僅是一個錯誤控制機制,也是一個通信媒介。因此,為了和同事更好的合作,一個團隊必須要制定出一個最佳實踐和規(guī)則,只有這樣,團隊成員才能理解這些通用概念,同時在工作中使用它。

異常處理-阿里巴巴Java開發(fā)手冊【強制】Java 類庫中定義的可以通過預(yù)檢查方式規(guī)避的RuntimeException異常不應(yīng)該通過catch 的方式來處理,比如:NullPointerException,IndexOutOfBoundsException等等。說明:無法通過預(yù)檢查的異常除外,比如,在解析字符串形式的數(shù)字時,可能存在數(shù)字格式錯誤,不得不通過catch NumberFormatException來實現(xiàn)。正例:if (obj != null) {…} 反例:try { obj.method(); } catch (NullPointerException e) {…}

【強制】異常不要用來做流程控制,條件控制。說明:異常設(shè)計的初衷是解決程序運行中的各種意外情況,且異常的處理效率比條件判斷方式要低很多。

【強制】catch時請分清穩(wěn)定代碼和非穩(wěn)定代碼,穩(wěn)定代碼指的是無論如何不會出錯的代碼。對于非穩(wěn)定代碼的catch盡可能進行區(qū)分異常類型,再做對應(yīng)的異常處理。說明:對大段代碼進行try-catch,使程序無法根據(jù)不同的異常做出正確的應(yīng)激反應(yīng),也不利于定位問題,這是一種不負責(zé)任的表現(xiàn)。正例:用戶注冊的場景中,如果用戶輸入非法字符,或用戶名稱已存在,或用戶輸入密碼過于簡單,在程序上作出分門別類的判斷,并提示給用戶。

【強制】捕獲異常是為了處理它,不要捕獲了卻什么都不處理而拋棄之,如果不想處理它,請將該異常拋給它的調(diào)用者。最外層的業(yè)務(wù)使用者,必須處理異常,將其轉(zhuǎn)化為用戶可以理解的內(nèi)容。

【強制】有try塊放到了事務(wù)代碼中,catch異常后,如果需要回滾事務(wù),一定要注意手動回滾事務(wù)。

【強制】finally塊必須對資源對象、流對象進行關(guān)閉,有異常也要做try-catch。說明:如果JDK7及以上,可以使用try-with-resources方式。

【強制】不要在finally塊中使用return。說明:try塊中的return語句執(zhí)行成功后,并不馬上返回,而是繼續(xù)執(zhí)行finally塊中的語句,如果此處存在return語句,則在此直接返回,無情丟棄掉try塊中的返回點。反例:

private?int?x?=?0;
public?int?checkReturn()?{
????try?{
????????//?x等于1,此處不返回
????????return?++x;
????}?finally?{
????????//?返回的結(jié)果是2
????????return?++x;
????}
}

【強制】捕獲異常與拋異常,必須是完全匹配,或者捕獲異常是拋異常的父類。說明:如果預(yù)期對方拋的是繡球,實際接到的是鉛球,就會產(chǎn)生意外情況。

【強制】在調(diào)用RPC、二方包、或動態(tài)生成類的相關(guān)方法時,捕捉異常必須使用Throwable類來進行攔截。說明:通過反射機制來調(diào)用方法,如果找不到方法,拋出NoSuchMethodException。什么情況會拋出NoSuchMethodError呢?二方包在類沖突時,仲裁機制可能導(dǎo)致引入非預(yù)期的版本使類的方法簽名不匹配,或者在字節(jié)碼修改框架(比如:ASM)動態(tài)創(chuàng)建或修改類時,修改了相應(yīng)的方法簽名。這些情況,即使代碼編譯期是正確的,但在代碼運行期時,會拋出NoSuchMethodError。

【推薦】方法的返回值可以為null,不強制返回空集合,或者空對象等,必須添加注釋充分說明什么情況下會返回null值。說明:本手冊明確防止NPE是調(diào)用者的責(zé)任。即使被調(diào)用方法返回空集合或者空對象,對調(diào)用者來說,也并非高枕無憂,必須考慮到遠程調(diào)用失敗、序列化失敗、運行時異常等場景返回null的情況。

【推薦】防止NPE,是程序員的基本修養(yǎng),注意NPE產(chǎn)生的場景:1) 返回類型為基本數(shù)據(jù)類型,return包裝數(shù)據(jù)類型的對象時,自動拆箱有可能產(chǎn)生NPE。反例:public int f() { return Integer對象}, 如果為null,自動解箱拋NPE。2) 數(shù)據(jù)庫的查詢結(jié)果可能為null。3) 集合里的元素即使isNotEmpty,取出的數(shù)據(jù)元素也可能為null。4) 遠程調(diào)用返回對象時,一律要求進行空指針判斷,防止NPE。5) 對于Session中獲取的數(shù)據(jù),建議進行NPE檢查,避免空指針。6) 級聯(lián)調(diào)用obj.getA().getB().getC();一連串調(diào)用,易產(chǎn)生NPE。正例:使用JDK8的Optional類來防止NPE問題。

【推薦】定義時區(qū)分unchecked / checked 異常,避免直接拋出new RuntimeException(),更不允許拋出Exception或者Throwable,應(yīng)使用有業(yè)務(wù)含義的自定義異常。推薦業(yè)界已定義過的自定義異常,如:DAOException / ServiceException等。

【參考】對于公司外的http/api開放接口必須使用“錯誤碼”;而應(yīng)用內(nèi)部推薦異常拋出;跨應(yīng)用間RPC調(diào)用優(yōu)先考慮使用Result方式,封裝isSuccess()方法、“錯誤碼”、“錯誤簡短信息”。說明:關(guān)于RPC方法返回方式使用Result方式的理由:1)使用拋異常返回方式,調(diào)用方如果沒有捕獲到就會產(chǎn)生運行時錯誤。2)如果不加棧信息,只是new自定義異常,加入自己的理解的error message,對于調(diào)用端解決問題的幫助不會太多。如果加了棧信息,在頻繁調(diào)用出錯的情況下,數(shù)據(jù)序列化和傳輸?shù)男阅軗p耗也是問題。

【參考】避免出現(xiàn)重復(fù)的代碼(Don’t Repeat Yourself),即DRY原則。說明:隨意復(fù)制和粘貼代碼,必然會導(dǎo)致代碼的重復(fù),在以后需要修改時,需要修改所有的副本,容易遺漏。必要時抽取共性方法,或者抽象公共類,甚至是組件化。正例:一個類中有多個public方法,都需要進行數(shù)行相同的參數(shù)校驗操作,這個時候請抽?。簆rivate boolean checkParam(DTO dto) {…}

轉(zhuǎn)自:thinkwon

thinkwon.blog.csdn.net/article/details/104390689


推薦閱讀:

世界的真實格局分析,地球人類社會底層運行原理

不是你需要中臺,而是一名合格的架構(gòu)師(附各大廠中臺建設(shè)PPT)

企業(yè)IT技術(shù)架構(gòu)規(guī)劃方案

論數(shù)字化轉(zhuǎn)型——轉(zhuǎn)什么,如何轉(zhuǎn)?

華為干部與人才發(fā)展手冊(附PPT)

企業(yè)10大管理流程圖,數(shù)字化轉(zhuǎn)型從業(yè)者必備!

【中臺實踐】華為大數(shù)據(jù)中臺架構(gòu)分享.pdf

華為的數(shù)字化轉(zhuǎn)型方法論

華為如何實施數(shù)字化轉(zhuǎn)型(附PPT)

超詳細280頁Docker實戰(zhàn)文檔!開放下載

華為大數(shù)據(jù)解決方案(PPT)

瀏覽 63
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 456成人| 91在线成人| 11一12周岁女毛片| 国产在线观看自拍| 中文字幕免费视频| 人人妻人人| 久久成人电影院| 亚洲秘无码一区二区三区| 久久九九视频| 最新精品视频| 黄色精品视频| 国产三级91| 精品欧美一区二区三区久久久| 国产成人视频免费在线观看| 艹逼视频免费观看| 安徽少妇搡bbw搡bbbb| 日韩天堂在线| 青青草激情视频| 激情五月天视频| 18禁一区二区| 九九成人精品| 欧美日韩亚洲一区二区三区| 午夜精品18码视频国产17c| 欧美自拍偷拍| 亚洲自拍电影| 中文字幕无码日韩| 欧美三级一级| 大香蕉草久| 日本一区二区精品| 亚洲v欧美v| 日韩成人片| 中文字幕+乱码+中文乱码www | 免费高清无码视频| 五月丁香婷婷在线| 日韩色色网| 欧一美一婬一伦一区二区三区黑人-亚| 日韩精品无码人妻| 久久青草影院| 亚洲黄色无码视频| 嫩BBB嗓BBBB榛BBBB| 成人a毛片| 一本高清无码| 无码人妻精品一区二区三区蜜臀百度 | 亚洲国产成人av| 欧美日韩A片欧美日| 国产精品久久777777| 日本精品一区二区三区四区的功能 | 加勒比综合网| 北京熟妇搡BBBB搡BBBB电影 | 99热免费在线| 极品久久久| 成年女人免费视频| 久草资源在线观看| 97精品人妻一区二区三区香蕉| 嫩草国产在线| 91精品91久久久中77777 | 成人精品毛片| 日韩有码一区| 玖玖爱免费视频| 日韩在线观看中文字幕| ThePorn精品无码| aaa国产精品| 亚洲色图一区二区| 日日骚中文字幕| 激情淫荡少妇| 美女黄网站| 伊人干综合| 91丨九色丨熟女老版| 亚洲精品无码久久久| 日日夜夜拍| 精品成人视频| 欧美VA视频| 亚洲精品ww| 夜夜撸日日| 国产做爰XXXⅩ久久久骚妇| 无码在线专区| 加勒比国产在线| 午夜精品一区二区三区在线成人 | 午夜神马福利| 人人干人人干人人| 色哟哟国产精品| 无码一| 中文字幕免费在线播放| 嫩草视频在线观看| www.狠狠爱| 欧美亚洲成人网| 成人中文字幕在线观看| 奇米色婷婷| 五月停亭六月,六月停亭的英语| 草草影院CCYYCOM屁屁影院合集限制影院 | 偷拍-91爱爱| 亚洲天堂视频在线播放| 青青草逼视频| yw视频在线观看| 亚洲精品久久久久毛片A级绿茶| AV第一福利大全导航| 色播国产成人AV| 在线免费观看成人视频| 国产精品v欧美精品v日韩| 午夜美女福利视频| 蜜桃人妻无码AV天堂三区| 中文激情网| 久久亚洲AV成人无码国产野外| 99re这里只有精品6| 亚洲福利在线免费观看| 三级网站在线播放| 欧美色图15P| 污视频免费在线观看| 国产在线黄片| 爱爱一区| 强伦轩人妻一区二区三区四区| 婷婷色在线观看| 久热福利视频| 亚洲加勒比在线| 日韩草逼| 国产在线h| 一本色道久久综合无码人妻| 亚洲免费专区| 日韩视频一区| 中文字幕一区二区蜜桃| 中文字幕自拍偷拍| 欧美熟妇擦BBBB擦BBBB| 无码人妻蜜桃| 欧美aⅴ| 777超碰| 黄色激情在线| 国产精品热| 网站你懂得| 亚洲综合色网| 三级片在线看片AV| 欧美自拍一区| 日韩一区二区三区四区久久久精品有吗| 欧美一级黃色A片免费看蜜桃熟了| 欧美操逼大片| 午夜成人在线视频| 久久久成人免费电影| 91成人视频在线播放| 国产一级AAAAA片免费| 国产一区二区三区在线| 黄色视频在线免费观| 中日韩精品A片中文字幕| 亚洲中文字幕日韩精品| 高清无码在线视频观看| 亚洲无码1区| 91女人18片女毛片60分钟| 免费无码一区二区三区| 欧美自拍视频| 麻豆videos| 人妻体内射精| 精品国内自产拍在线观看视频| 日本色视频| 欧美黄色三级片| 午夜无码福利| 操逼无码| 亚洲视频1区| 亚洲天堂国产视频| 日韩久久中文字幕| 麻豆高清无码| 婷婷五月综合网| 五月婷婷中文字幕| 做爱网站在线观看| 黑人aV| 久久国产一区二区三区| 丝袜一区| 日批视频网站| 久久人搡人人玩人妻精AV香蕉| 久久午夜鲁丝| 蜜臀久久精品久久久久| 一级黄色在线| 国产精品久久久久久久久久九秃 | 免费观看在线无码视频| 日本A片在线播放| 午夜精品18| 一本一道久久综合狠狠躁牛牛影视| 中文字幕视频在线免费观看| 国产精品自拍在线观看| a欧美| 人妻操逼| 国产三级黄色视频| 成人无码欧美大片免费看| 黑人毛片91久久久久久| 黄色视频在线观看免费网站| 美女黄片| 成人小说视频在线社区| 国产免费国产| 中文字幕av免费在线观看| 北条麻妃av在线播放| 五月丁香成人网| 91在线免费视频| 国产精品久久久久久最猛| 翔田千里中文字幕无码| 成人亚洲A片V一区二区三区蜜月 | 亚洲毛片网站| 日本91| jizz在线免费观看| 国产激倩都市一区二区三区欧美| 99视频自拍| 91九色TS另类国产人妖| 国产h视频| 欧美一级爱爱| 黄色网址五月天| 影音先锋av成人电影| 免费播放婬乱男女婬视频国产| 国产欧美日韩在线观看| 国产人妻一区二区三区欧美毛片| 国产精品香蕉国产| 337P人体美鮑高清| 91黄色电影| 亚洲美女喷水视频| 亚洲熟妇在线观看| 18禁av在线| 超碰777| 欧美成人图片视频在线| 亚洲精品美女视频| 亚洲日韩欧美在线观看| 精品中文字幕在线观看| 日韩一级无码毛片| 国产最新av| 99精品丰满人妻无码| 一级AA片| 一级片操逼| 久久熟女嫩草成人片免费| 亚洲天堂2015| 成人AV免费观看| 十八禁网站在线播放| 久久精品www人人爽人人| 91麻豆成人| 日韩成人AV在线播放| 国产一级片免费| 亚洲视频在线免费播放| 欧洲黑种人日P视频| 18精品爽视频| 久久99精品久久久水蜜桃| 成人三级毛片| 中文字幕在线免费视频| 嫩BBB槡BBBB槡BBB小号| 日韩无码AV一区二区三区| 日逼电影网| 高颜值呻吟给力| 亚洲av小说| 91性爱网| 国产中文| 黄色片视频日韩| 日日夜夜AV| 人妻人人爽| 一级婬片A片AAAAA毛片| 91黑人| 成人做爰A片一区二区| 性欧美丰满熟妇XXXX性久久久| 99er在线观看视频| 日本免费黄色片| 91天天综合在线| 国产videos| 国产成人免费在线| 人人操人人操人人操人人操人人操| 国产亚洲精品久久久久久桃色| 午夜视频在线播放| 国产十欧洲十美国+亚洲一二三区在线午夜| 少妇搡BBBB搡BBB搡小说 | 国产一视频| 国产精品秘久久久久久一两个一起| 爱草视频| 熟女资源网| 91精品婷婷国产综合久久| 国产黄片视频| 国产无码电影在线观看| 中文在线字幕高清电视剧| 一级色色片| 国产性猛交╳XXX乱大交| 久久无码高清视频| 中文大香蕉视频| 日本一本草久p| 人人操操| 91一区在线观看| 大香蕉中文网| 国产美女自拍| 午夜福利澳| 1级毛片| 91网在线观看| 国产久久精品| 欧美日韩狠狠操在线观看视频| 波多野结衣久久精品| 成人在线国产| 亚洲国产成人无码| 婷婷五月无码| 亚洲无码影视| 在线视频福利导航| 日本黄网站| 亚洲欧美日韩不卡| 蜜臀久久99精品久久久兰草影视| 日韩欧美高清| 国产白丝精品91爽爽久久| 人人妻人人澡人人爽人人DVD| 四川妇搡BBBB搡BBBB| 国产香蕉视频在线观看| 免费av在线| 中文字幕免费无码| 国产成人精品一区二三区熟女在线 | 激情视频免费看| 福利国产在线| 成人免费视频在线观看| 99久久国产热无码精品免费| 欧美性爱视频免费看| 成人中文字幕网站| 中文字幕av久久爽Av| 亚洲最大三级片| 国产精品一区二区三区在线| av无码aV天天aV天天爽| 亚洲天天在线| 亚洲自拍偷拍视频| 18禁在线看| 日韩欧美高清第一期| 91精品人妻人人爽| 18禁激韩| 欧美激情内射| 亚洲三级在线视频| 亚洲福利视频97| 亚洲少妇熟女| 国产操屄视频| 伊人黄色片| 免费看一级无码成人片| 久久AV无码| 高清无码视频在线免费观看| 一级婬片A片AAAAA毛片| 四川女人毛多水多A片| 亚洲欧美激情小说另类| 国产综合久久久7777777| 日韩99热| 国产三级AV在线| 中文字幕中文字幕一区| 色婷婷中文| 影音先锋人妻限定| 五月天婷婷激情视频| 午夜操| 国产精品天天狠天天看| www.操逼| 国产综合区| 综合网亚洲| 北条麻妃三区| 久久黄色网| 色噜噜人妻av中文字幕| 大香蕉A片| 婷婷五月中文| 女毛片| 91麻豆视频在线观看| 日韩操片| 日韩精品无码AV| 日韩精品一区在线观看| 94精品人人人| 国产一卡二卡在线观看| 免费AV观看| 又黄又爽的网站| 国产麻豆AⅤMDMD0071| ww免费视频| 操逼视频网| 国产高清无码一区| 欧美三级片在线| 91精品国产乱码久久久| 91香蕉国产视频| 奇米色色| 在线亚洲AV| 国产精品性爱视频| 亚洲欧美在线综合| 人人看人人爱| 另类老妇性BBBWBBW| 精品77777| 草久美女| 久久一区二区三区四区五区| 黄频免费观看| 翔田千里无码播放| AV三级无码| 国产精品美女视频| AAA片网站| 成人午夜在线| 男人天堂V| 手机在线看片av| 超碰最新在线| 久草精品在线| 亚洲午夜无码| 少妇搡BBBB搡BBB搡18禁| 日本色网站| 无码国产99精品久久久久网站| 免费黄色视频在线| 亚洲口味重一级黄片| 性生活黄色视频| 日本黄色精品| 国精品伦一区一区三区有限公司| 97精品超碰一区二区三区| 熟妇一区| 日本理论片一道本| 亚洲国产精品自在自线| 午夜蜜桃人妻一区二区| 国产无码久久久| av电影在线观看| 荫蒂添到高潮免费视频| 亚洲无码二区| 国产一区二区三区四区五区六区七区 | 农村乱子伦毛片国产乱| 成人18视频| 久久av一区二区三区| 男女av网站| 无码乱伦| 九色PORN视频成人蝌蚪自拍 | 欧美色爽| 亚洲成人国产| 特级欧美AAAAAA| www.91n| 99精品国产一区二区| 高清无码免费观看| 亚洲热视频在线观看| 亚洲三级网站| 成年免费视频| 在线观看视频91| 国产一精品一aⅴ一免费| 超碰成人在线观看| 国产毛片久久久久久久| 亚洲色在线播放| 91好爽| 欧美操逼操| 51黄片| 日批网站视频| 天天射中文| 91在线资源| 日韩三级av| 精品国产AV鲁一鲁一区| 日本三级网| 黄色工厂这里只有精品| 一本久久A精品一合区久久久| 北条麻妃无码| 日韩欧美视频在线播放| 人人操人人爱人人拍| 内射91| 欧美大鸡巴在线观看| 在线观看亚洲| 久久成人导航| www.豆花社区成人| 色婷婷在线视频| 亚洲性爱影院| 粉嫩99精品99久久久久久特污 | 亚洲日韩中文字幕| 91.www91成人影视在线观看91成人网址9 | 日韩七区| 999无码| 日韩AV无码专区亚洲AV| 国产精品一区二区黑人巨大| 江苏妇搡BBBB搡BBBB小说| 日本乱伦网| 五月丁香婷婷开心| 亚洲无码在| 国产丝袜在线视频| 亚洲色成人中文字幕在线| 婷婷六月天| 丰满岳乱妇一区二区三区全文阅读| 2024av在线| 天天色视频| 欧美精产国品一区二区区别| 秋霞丝鲁片一区二区三区手机在绒免 | 黄色毛片,男人天堂| 欧美成人午夜视频| 青春草在线播放| 亚洲国产操逼| 操逼视频在线播放| 熟女人妻ThePorn| 青青激情视频| 欧美中文字幕在线| 婷婷综合五月天| 特黄无码| 国产欧美精品在线观看| 免费A片国产毛无码A片| 人妻天天操| 亚洲最新在线观看| 成人黄色在线| 国产色哟哟| 日韩精品丰满无码一级A片∴| 黄色九九| 一夲道无码专区av无码A片| 特级西西人体WWWWW| 人人操人人人| 精品人妻一区二区三区四区| 久久精品成人电影| 日本黄色电影在线| 爱搞视频| 精品一区二区三区蜜桃臀www| 久久xx| 午夜69成人做爱视频网站| 日本视频在线免费| 躁BBB躁BBB躁BBBBBB| 国产精品国产精品国产专区 | 爆草美女| 中文字幕亚洲第一| 久热精品在线| 肏逼网| 91免费视频观看| 一级无码在线观看| 欧美亚洲日韩一区| 日本一级特黄电影| 日韩极品视频| 97人妻精品一区二区三区图片| 国产日逼片| 日韩草比| 香蕉伊人网| 99免费在线观看视频| 色噜噜人妻av中文字幕| 噜噜噜噜射| 超碰中文字幕| 麻豆国产精品| 国产亚洲天堂| 免费观看黄片网站| 抠骚逼| 内射少妇18| 欧美午夜精品成人片在线播放 | 在线综合国产欧美| 精品在线免费观看| 亚洲成人观看| 国产乱人伦无码视频| 久久久久久免费一级A片| 影音先锋资源| 日韩午夜精品| 91av免费| 欧美午夜爱爱| 台湾AV在线| 久久精品视频观看| 国产在线观看免费视频| 亚洲欧美日韩电影| 抽插免费视频| 日本黄色电影在线播放| 免费a片观看| 久久久一区二区三区四区免费听 | 无码av中文字幕| 国内自拍偷拍视频| 在线免费观看av网站| 国产精品视频瘾无码| 青青草大香蕉| 丁香五月激情在线| 啪啪啪AV| 51成人免费| 久久一区二区三区四区| 日本A∨| 在线观看免费国产| 日韩久久久久| 国产熟女自拍| 蜜臀久久99精品久久一区二区 | 黄色电影天堂| 欧美日在线观看| 91国产免费视频| 日韩99在线观看| 91久久精品日日躁夜夜躁国产| 日韩人妻在线视频| 一区二区三区四区免费看| 亚洲秘无码一区二区三区电影| 精品人妻人人操| 婷婷色色五月天图片| 国产三级片视频| 婷婷午夜精品久久久久久性色AV | 超碰大香蕉| 高清无码在线观看18| 高清无码中文字幕在线观看| 亚洲先锋影音| 午夜无码福利在线观看| 大香蕉伊人青青草| 国产18欠欠欠一区二区| 91AV在线播放| 超碰手机在线| 亚洲无码精品在线观看| 国产一区二区三区在线观看免费视频免费视频免费视频 | 欧一美一婬一伦一区二区三区自慰国| 国产性爱电影网| 熟女导航| 蜜桃精品视频| 无码啪啪啪| 91精品国产麻豆国产自产在线 | 一本色道无码道| 免费伊人大香蕉| 国产内射久久| 亚洲jizzjizz| 在线观看AV无码| 黄片在线免费观看| 亚洲色诱| 西西444WWW大胆无视频软件亮点| 婷婷色网站| 国产三级片精品| 久久婷婷国产麻豆91天堂| 亚洲成人精品AV| 色色色五月婷婷| 亚洲无码免费视频在线观看| 91双飞会所双飞在线| 无码中文视频| 豆花视频| 国产欧美日韩在线观看| 久久久亚洲熟妇熟女| 成全在线观看高清的| 久草性爱| 无码区一区二区| 超碰牛牛| 大香蕉伊人色| AV高清无码在线观看| 无码人妻精品一区二区三区温州| 中文字幕日日| 短发妹子双人啪啪秀| 99精品视频在线| 精产国品一区二区区别| 国产精品美女毛片真酒店| 成人网站av| 欧美日韩视频在线播放| 成年人视频在线免费观看| 日韩无码视频网站| 精品中文字幕在线| 久久8| 午夜精品久久久久久久91蜜桃| 亚洲无码久久网| 国外操逼视频| 毛片入口| 日韩性爱视频在线播放| 亚洲高清人妻| 北条麻妃在线观看香蕉| 91麻豆大奶巨乳一区白虎| 欧美日韩成人| 久久人体| 国产黄色在线视频| 久久爱成人| 韩国无码免费| 91麻豆精品传媒国产| V天堂在线| 国产性爱网址| 99九九久久| 亚洲内射视频| 青娱乐国产在线视频| 神马午夜| 美女操逼网站| 丁香婷婷六月天| 久久福利社| 国产亚洲91| 日韩在线视频中文字幕码无| 天干夜天干天天天爽视频| 日韩天堂在线观看| 嫩草91| 五月激情六月| 中文字幕高清| 狼人一区二区| 欧美囗交大荫蒂免费| 十八女人高潮A片免费| 亚洲无码AV一区二区| 2025中文字幕在线| 欧美mv日韩mv国产| 午夜性福利视频| xxxxxbbbbb| 亚洲欧洲天堂| 波多野结衣在线观看一区二区 | 麻豆免费福利视频| 韩剧《邻居的妻子》电视剧| 久久内射| 色999网址| 中文字幕在线观看1| 无码中文字幕高清| 丰满人妻一区二区免费看| 大香蕉精品欧美色综合2025| 亚洲人在线观看| 人人操人人操人人操人人操人人操| 日韩老熟妇| 韩国精品一区| 成年人免费黄色视频| 国产精品无码成人AV电影| 婷婷精品秘进入| 日韩AV资源网| 91大神在线免费观看| 成人丁香五月天| 亚洲色图五月天| 嫩BBB槡BBBB槡BBBB百度| 波多野结衣在线观看一区二区 | 亚洲无码AV麻豆| 激情无码网站| 人人爽亚洲AV人人爽AV人人片 | 欧美老逼| 91蝌蚪| 亚洲视频第一页| 国精产品一区二区三区| 三级A片| 欧美熟妇精品一二三区| 黄色视频一区二区| 日韩大黄| 无码日逼视频| 亚洲成人动漫在线| 东京热av一区二区| 51妺妺嘿嘿午夜成人| 人妻在线免费视频| 亚洲超碰在线观看| a欧美| 中文字幕亚洲高清| 欧美三级毛片| 欧美成人三区性价比| 五月婷婷六月激情| 加勒比综合在线| 欧美日韩在线免费观看| 男人天堂手机视频| AV一二区| 天堂综合网久久| 高清无码视频直接看| 色情小电影免费网站观看网址在线播| 国产老骚逼| 一本色道久久综合无码| 91丨九色丨熟女丰满| 久久成人综合| 污视频免费在线观看| 狠狠躁日日躁夜夜躁A片无码视频 强伦轩一区二区三区四区播放方式 | 国产视频一区二区在线| 青草成人在线| 一本久久综合亚洲鲁鲁五月天| 操极品少妇逼| 国产毛片一区| 国产亚洲91| 日韩家庭乱伦| 国产XXXXX| 99香蕉视频| 91乱伦| 欧美色一级| 爽爽午国产浪潮AV性色www| www日本在线| 亚洲一区二区成人| 亚洲秘一区二区三区-精品亚洲二区- | 亚洲精品久久久久久久久久久| 丁香五月天网站| 日韩人妻一区二区三区| 天天干天天爽| 女人自慰网站在线观看| 国产欧美日韩综合精品| 亚洲成人影音先锋| 亚洲天堂无码AV| 成人无码久久| 久久精品一区二区三区蜜芽的特点| 亚洲专区视频| 奇米影视亚洲春色| 88海外华人免费一区| 日本色影院| 午夜精品久久久久久久91蜜桃| а中文在线天堂精品| 超碰97在线免费观看| 人人妻人人操人人| 天堂综合网| 国产操穴视频| 中文字幕成人网站中文字幕| 欧美日韩一区二区在线| 中文在线观看免费视频| 日批国产| 中文字幕乱码人妻二区三区| 国产精品毛片| 伊人网在线免费视频| 51伦理| 黄片免费高清| 日韩操B视频| 黄色av天堂| 丁香婷婷男人天堂| 无遮挡动态图| 日本特黄一级| 欧一美一婬一伦一区| 亚洲女人视频| 亚州一级二级| 亚洲第一伊人| 超碰2025| 亚洲中文字幕日韩精品| 亚洲AV无码成人精品区东京热| 亚洲砖区| 日韩精品在线一区| 亚洲一区欧美| HEZ-502搭讪绝品人妻系列| 成人亚洲AV| 国产伊人久久| 老骚老B老太太BBW| 日本中出视频| 九九成人精品| 无码内射在线播放| 91人人人| 成人精品无码| 做aAAAAA免费视频| 91av一区二区三区| 伊人久久香| 日韩无码A片| 91老熟女| 国产激情精品视频| 波多野结衣av在线观看| 男女日逼网站| 久草免费在线| 看一级黄色毛片| 五月天啪啪视频| BBB搡BBB搡BBB搡BBB| 老熟女一区二区三区| 高清一区二区三区| 国产精品AV网站| 成人影视在线免费观看| 免费观看一区二区三区| 色天堂视频| 91爱爱| 成年视频在线观看| 黄色视频毛片| 日本少妇无码| 国产美女自拍| 色综合社区| av婷婷五月天| 美女啪啪视频| 欧美日韩中文字幕| 99r6热只有精品免费观看| 色色五月天视频| 国产理论电影在线观看| 四川妇BBB桑BBB桑BBB| 国产日韩在线播放| 色网站操逼| 成人av天堂| 中文字幕一级A片免费看| 日韩AV无码高清| 66久久| 91在线视频精品| 中国免费视频高清观看| 蜜桃影院| 91福利在线视频| 99热视| 欧洲成人无码| 免费黄片在线| 黄片在线免费观看视频| 一区二区三区av| 黄色视频在线观看大全| 丰满人妻一区二区三区免费| 日本A片视频| 最新AV在线播放| 成人无码网站在线观看| 亚洲AV无码精品成人| 淫色视频| 国产三级成人| 天天日夜夜拍| 久久少妇视频| 91大神免费在线观看| 婷婷深爱激情| 欧美色视频在线观看| 狠狠躁日日躁夜夜躁A片无码视频 强伦轩一区二区三区四区播放方式 | 蜜桃人妻| 九九精品热播| 俺去也视频| 91麻豆天美传媒在线| 久久无码在线观看| 蜜桃AV一区二区三区| 在线不卡免费Av| 亚洲日本三级| 日韩av免费看| 亚洲无码久久久| 波多野结衣av一区| 久久久久久久大香蕉| 日韩日逼视频| 欧美干综合| 五月天久久| 国产不卡在线| 久久综合加勒比| 肏屄视频网站| 99热精品在线播放| 麻豆精品在线播放| 日韩大鸡巴| 成人免费视频18| 蜜臀久久99精品久久一区二区| 激情五月伊人| 五月丁香激情视频| 人妻三级| 色老板在线观看视频| 国产一级a毛一级做a爱| 亚洲国产成人精品综合99| 欧美在线| 色哟哟一区二区三区| 久草一区二区三区| 亚洲尤物| 国产理论电影| 亚洲日韩中文字幕无码| 国产午夜成人免费看片无遮挡| www.91久久| 久久久久少妇| 裸体美女视频欧美18| 日本18禁网站| 高清无码高潮| 日韩性做爰免费A片AA片| 狠狠色婷婷| 亚洲中文免费观看| 琪琪色在线观看| 中文字幕av高清片,中文在线观看| a√天堂资源中文8| 99精品人妻| 手机AV免费| 亚洲精选中文字幕| 欧美不卡| 亚洲最新在线观看| 影音先锋AV在线资源| 好吊一区二区三区| 北条麻妃91视频| 国产成人av在线| 久久久久久久久久免费视频| 亚洲中文字幕2019| 亚洲综合小说| 成年片免费观看网站免费观看,亚洲+欧... | 欧美伊人大香蕉| 欧美乱伦视频| 亚洲色图五月天| 人人操大香蕉| 一级a片在线免费观看| 99看片| 18禁免费网站| 亚洲精品成人网站|