準(zhǔn)備校招,關(guān)于JAVA 異常,面試看這篇就夠了

      網(wǎng)友投稿 835 2022-05-29

      寫在前面

      溫習(xí)一下畢業(yè)以來(lái)學(xué)習(xí)的東西。準(zhǔn)備做成一個(gè)系列。所以對(duì)于每一部分技術(shù)點(diǎn)進(jìn)行一個(gè)筆記整理。

      筆記主要是以《Effective Java》、 《編寫高質(zhì)量代碼(改善Java程序的151個(gè)建議)》這兩本書為方向進(jìn)行整理。

      在不斷更新,博文內(nèi)容理解不足之處請(qǐng)小伙伴留言指正

      傍晚時(shí)分,你坐在屋檐下,看著天慢慢地黑下去,心里寂寞而凄涼,感到自己的生命被剝奪了。當(dāng)時(shí)我是個(gè)年輕人,但我害怕這樣生活下去,衰老下去。在我看來(lái),這是比死亡更可怕的事。--------王小波

      一、JAVA 異常分類及處理

      異常概述

      程序中的錯(cuò)誤可分為語(yǔ)法,邏輯,運(yùn)行時(shí)錯(cuò)誤。程序在運(yùn)行時(shí)的錯(cuò)誤被稱為異常。

      白話講解:如果已知某個(gè)方法不能按照正常的途徑完成任務(wù),就可以通過(guò)另一種路徑退出方法。在這種情況下會(huì)拋出一個(gè)封裝了錯(cuò)誤信息的對(duì)象。此時(shí),這個(gè)方法會(huì)立刻退出同時(shí)不返回任何值。另外,調(diào)用這個(gè)方法的其他代碼也無(wú)法繼續(xù)執(zhí)行,異常處理機(jī)制會(huì)將代碼執(zhí)行交給異常處理器。

      Throwable

      Throwable 是 Java語(yǔ)言中所有錯(cuò)誤或異常的超類。下一層分為 Error 和 Exception

      如果面試被問(wèn)到異常是如何定位到的異常位置的,你會(huì)怎樣回答?:

      JVM在創(chuàng)建一個(gè)Throwable類及其子類時(shí)會(huì)把當(dāng)前線程的棧信息記錄下來(lái),以便在輸出異常時(shí)準(zhǔn)確定位異常原因,在出現(xiàn)異常時(shí),JVM會(huì)通過(guò)fillInStackTrace(填寫執(zhí)行堆棧跟蹤。)方法記錄下棧幀的信息,然后生成一個(gè)Throwable對(duì)象,可以知道類間的調(diào)用順序,方法名稱及當(dāng)前行號(hào)。

      簡(jiǎn)單看一下源碼

      ...... * @since JDK1.0 */ public class Throwable implements Serializable { /** * A shared value for an empty stack. */ //出現(xiàn)異常的棧記錄 private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0]; ...... private StackTraceElement[] stackTrace = UNASSIGNED_STACK; ...... //構(gòu)造函數(shù)記錄棧幀 public Throwable() { fillInStackTrace(); } ..... //調(diào)用本地方法,抓取執(zhí)行時(shí)的棧信息。 public synchronized Throwable fillInStackTrace() { if (stackTrace != null || backtrace != null /* Out of protocol state */ ) { fillInStackTrace(0); stackTrace = UNASSIGNED_STACK; } return this; } //本地方法.抓取執(zhí)行時(shí)的棧信息。 private native Throwable fillInStackTrace(int dummy); ...... }

      Error

      Error 類是指java 運(yùn)行時(shí)系統(tǒng)的內(nèi)部錯(cuò)誤和資源耗盡錯(cuò)誤。應(yīng)用程序不會(huì)拋出該類對(duì)象。如果出現(xiàn)了這樣的錯(cuò)誤,除了告知用戶,剩下的就是盡力使程序安全的終止。Error中面試常考OOM類型的問(wèn)題, 內(nèi)存溢出、泄露之類。

      如果面試被問(wèn)起來(lái)OOM,你會(huì)怎樣簡(jiǎn)單描述下?:

      所謂OOM,即 java.lang.OutOfMemoryError:翻譯成中文就內(nèi)存用完了,當(dāng)JVM因?yàn)闆](méi)有足夠的內(nèi)存來(lái)為對(duì)象分配空間,并且 垃圾回收器 也已經(jīng) 沒(méi)有空間可回收時(shí),就會(huì)拋出這個(gè)error。我知道的,造成OOM的有兩種,內(nèi)存溢出和GC占用大量時(shí)間釋放很小空間(GC overhead limit exceeded)。

      內(nèi)存溢出:申請(qǐng)的內(nèi)存超出了JVM能提供的內(nèi)存大小,此時(shí)稱之為溢出,可選的解決辦法是調(diào)整JVM參數(shù),造成溢出原因也可能是因?yàn)閮?nèi)存泄漏,所謂內(nèi)存泄漏,即申請(qǐng)使用完的內(nèi)存沒(méi)有釋放,導(dǎo)致虛擬機(jī)不能再次使用該內(nèi)存,此時(shí)這段內(nèi)存就泄露了,因?yàn)樯暾?qǐng)者不用了,而又不能被虛擬機(jī)分配給別人用。

      GC占用大量時(shí)間釋放很小空間:JVM花費(fèi)了98%的時(shí)間進(jìn)行垃圾回收,而只得到2%可用的內(nèi)存,頻繁的進(jìn)行內(nèi)存回收(最起碼已經(jīng)進(jìn)行了5次連續(xù)的垃圾回收),JVM就會(huì)曝出java.lang.OutOfMemoryError: GC overhead limit exceeded錯(cuò)誤。即超出了GC開銷限制。是JDK6新添的錯(cuò)誤類型。是發(fā)生在GC占用大量時(shí)間為釋放很小空間的時(shí)候發(fā)生的,是一種保護(hù)機(jī)制。一般是因?yàn)槎烟。瑢?dǎo)致異常的原因:沒(méi)有足夠的內(nèi)存。

      如果面試官問(wèn)OOM的發(fā)生在JVM那些內(nèi)存區(qū)域:要怎么回答?:

      OOM會(huì)發(fā)生在java虛擬機(jī)棧,本地方法棧,java 堆,以及運(yùn)行時(shí)常量池中。

      對(duì)于java虛擬機(jī)棧來(lái)講,當(dāng)線程的請(qǐng)求棧深度大與虛擬機(jī)所允許的深度的時(shí)候。將拋出StackOverflowError異常。如果虛擬機(jī)棧可以動(dòng)態(tài)擴(kuò)展,但擴(kuò)展時(shí)無(wú)法申請(qǐng)到足夠的內(nèi)存,就會(huì)拋出OutOfMemoryError異常.

      本地方法棧與虛擬機(jī)棧類似,區(qū)別是虛擬機(jī)棧為虛擬機(jī)執(zhí)行的Java方法服務(wù),而本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)。也會(huì)拋出StackOverflowError異常,OutOfMemoryError異常。

      故所周知,java堆是虛擬機(jī)所管理的內(nèi)存最大的一塊,是被所有線程共享的一塊內(nèi)存區(qū)域。幾乎所有的實(shí)例以及數(shù)組都要在堆上分配空間。同時(shí),java堆也是GC的主要區(qū)域,也被稱為GC堆,如果在堆中沒(méi)有內(nèi)存完成實(shí)例分配,并且堆中也無(wú)法擴(kuò)展,會(huì)拋出OutOfMenory異常。

      運(yùn)行時(shí)常量池,是方法區(qū)的一部分,當(dāng)常量池?zé)o法在申請(qǐng)內(nèi)存時(shí)會(huì)拋出OutOfMethodError異常。java8之后改變了永久代的位置,存放到了直接內(nèi)存,所以這部分的溢出算到直接內(nèi)存溢出。

      關(guān)于更多這方面的知識(shí)推薦小伙伴去看《深入理解Java虛擬機(jī)》這本書。關(guān)于上面講的溢出實(shí)例代碼,小伙伴可移步到博客java中OOM錯(cuò)誤淺析(沒(méi)有深入太多,一些粗淺的知識(shí),可以溫習(xí)用)

      Exception

      Exception又有兩個(gè)分支,一個(gè)是運(yùn)行時(shí)異常RuntimeException ,一個(gè)是檢查異常CheckedException,如 I/O 錯(cuò)誤導(dǎo)致的 IOException、SQLException。

      如果面試官問(wèn)受檢異常和非受檢異常的區(qū)別的時(shí)候,要怎么回答?

      非檢查型異常RuntimeException 如 :NullPointerException 、ClassCastException ;RuntimeException是那些可能在 Java 虛擬機(jī)正常運(yùn)行期間拋出的異常的超類。 如果出現(xiàn)RuntimeException,那么一定是程序員的錯(cuò)誤.

      檢查異常 CheckedException:一般是外部錯(cuò)誤,這種異常都發(fā)生在編譯階段,Java 編譯器會(huì)強(qiáng)制程序去捕獲此類異常,即會(huì)出現(xiàn)要求你把這段可能出現(xiàn)異常的程序進(jìn)行 try catch,該類異常一般包括幾個(gè)方面:

      試圖在文件尾部讀取數(shù)據(jù)

      試圖打開一個(gè)錯(cuò)誤格式的 URL

      試圖根據(jù)給定的字符串查找 class 對(duì)象,而這個(gè)字符串表示的類并不存在

      異常的處理方式

      捕獲異常

      將可能出現(xiàn)的異常的代碼放到try語(yǔ)句中進(jìn)行相應(yīng)的隔離,如果遇到異常,程序會(huì)停止執(zhí)行try塊的代碼,自動(dòng)生成一個(gè)異常對(duì)象,該異常對(duì)象被提交給Java運(yùn)行時(shí)環(huán)境(拋出異常),Java運(yùn)行時(shí)環(huán)境收到異常對(duì)象時(shí),跳到catch塊中進(jìn)行處理(即與catch中的異常對(duì)象一一匹配),匹配成功執(zhí)行相應(yīng)的catch塊語(yǔ)句(捕獲異常)。

      如果面試官問(wèn)異常捕獲有幾種方式,要怎么回答?

      多異常單獨(dú)捕獲

      try{ //可能出現(xiàn)異常的代碼 }catch(異常類 異常對(duì)象){ //該異常類的處理代碼 }catch(異常類 異常對(duì)象){ } // 可以有多個(gè)catch語(yǔ)句。 // 在執(zhí)行多catch語(yǔ)句時(shí),當(dāng)異常對(duì)象被其中的一個(gè)catch語(yǔ)句捕獲時(shí), 剩下的catch語(yǔ)句將不會(huì)進(jìn)行匹配。 // 在安排順序時(shí),首先應(yīng)該捕獲一些子類異常,然后在捕獲父類異常。即父類異常必須放到子類的后面,同一級(jí)不影響。

      多異常統(tǒng)一捕獲

      try{ //業(yè)務(wù)實(shí)現(xiàn)代碼(可能發(fā)生異常) }catch(異常類1[|異常類2|異常類3……] 異常對(duì)象){ //多異常捕獲處理代碼 } //多異常捕獲時(shí),異常變量默認(rèn)是常量,因此不能對(duì)該異常變量重新賦值。

      所有異常對(duì)象都包含一下幾個(gè)常用的方法用于訪問(wèn)異常信息:

      getMessage() 返回該異常的詳細(xì)描述字符串(類型,性質(zhì))

      printStackTrace() 將該異常的跟蹤棧信息輸出到標(biāo)準(zhǔn)錯(cuò)誤輸出

      printStackTrace(PrintStream s) 將該異常的跟蹤棧信息出現(xiàn)在程序中的位置輸出到指定的輸出流

      getStackTrace() 返回該異常的跟蹤棧信息

      toString() 返回異常發(fā)的類型與性質(zhì)

      防止try中出現(xiàn)異常無(wú)法回收物理資源,finally塊中放回收代碼,顯示回收在try中打開的物理資源。不管try塊中是否出現(xiàn)異常,也不管catch塊中是否執(zhí)行return語(yǔ)句,finally總會(huì)被執(zhí)行(不被執(zhí)行的情況:finally語(yǔ)句發(fā)生異常,使用了System.exit(0)語(yǔ)句,線程死亡,關(guān)閉cpu)。

      如果面試官問(wèn)異常捕獲中 只有try和finally沒(méi)有catch可以不,是語(yǔ)法錯(cuò)誤嗎?要怎么回答?

      有catch的情況

      try{ //可能發(fā)生異常的代碼 }catch(異常類 異常類對(duì)象){ //異常類的處理代碼 }finally{ //資源回收語(yǔ)句 }。 //try塊時(shí)必須的,catch塊與finally塊時(shí)可選的,即try……finally或try……catch……finally(順序不能顛倒);

      沒(méi)有catch的情況

      try塊時(shí)必須的,catch塊與finally塊時(shí)可選的,即try……finally或try……catch……finally(順序不能顛倒);

      try{ //可能發(fā)生異常的代碼 }finally{ //資源回收語(yǔ)句 }

      1.7之后可以使用自動(dòng)關(guān)閉的資源的try語(yǔ)句,但是被釋放的資源必須實(shí)現(xiàn)AutoCloseable接口, AutoCloseable對(duì)象的close()方法在退出已在資源規(guī)范頭中聲明對(duì)象的try -with-resources塊時(shí)自動(dòng)調(diào)用。 這種結(jié)構(gòu)確保迅速釋放,避免資源耗盡異常和可能發(fā)生的錯(cuò)誤。

      如果面試被問(wèn)到try-with-resources的使用有什么限制么?怎么回答?

      前提是必須實(shí)現(xiàn)了AutoCloseable接口才可以

      如果面試被問(wèn)到try-with-resources可以有catch和finally 嗎,可以只有try嗎?怎么回答?

      有catch和finally 的情況

      try (Connection connection = DriverManager.getConnection("")) { } catch (SQLException e) { e.printStackTrace(); }finally { }

      沒(méi)有catch塊,受檢異常需要顯示聲明

      static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } }

      try() 中()多條語(yǔ)句

      @Override public void run() { try( // 拿到輸入流 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 拿到輸出流 PrintWriter out = new PrintWriter(socket.getOutputStream()) ){ while (true){ String str = in.readLine(); if (str == null){ continue; } System.out.println("接受原始消息"+str); // CONSUME表示消費(fèi)一條消息 if ("CONSUME".equals(str)){ String s = Broker.consume(); out.println(s); out.flush(); }else { // 其他情況表示生產(chǎn)消息放到消息隊(duì)列里面 Broker.produce(str); } } }catch (Exception e){ e.printStackTrace(); } }

      如果面試被問(wèn)到異常塊可以嵌套么?怎么回答?

      使用嵌套的try...catch語(yǔ)句,當(dāng)內(nèi)部的try塊沒(méi)有遇到匹配的catch塊則檢查外部的catch塊。

      try { try { }catch (ArrayIndexOutOfBoundsException e){ e.printStackTrace(); } }catch (Exception e ){ e.printStackTrace(); }

      public static String fileToBufferedReader(InputStreamPeocess inputStreamPeocess, File file) { try (FileInputStream fileInputStream = new FileInputStream(file)) { try (InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream)) { try (BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) { return inputStreamPeocess.peocess(bufferedReader); } } } catch (IOException e) { e.printStackTrace(); } }

      拋出異常:

      如果面試官問(wèn)throw和throws有啥區(qū)別?要怎么回答?

      thorw:使用throw拋出一個(gè)異常對(duì)象,當(dāng)程序出現(xiàn)異常時(shí),系統(tǒng)會(huì)自動(dòng)拋出異常,也可以使用throw語(yǔ)句自動(dòng)拋出一個(gè)異常。throw語(yǔ)句拋出的不是異常類,而是一個(gè)異常實(shí)例對(duì)象,且每次只能拋出一個(gè)異常實(shí)例對(duì)象。

      throw new 對(duì)象名();

      thorws:使用throws聲明拋出異常。使用throws聲明一個(gè)異常序列:當(dāng)前方法不知道如何處理異常時(shí),該異常應(yīng)有上一級(jí)調(diào)用者進(jìn)行處理,可在定義該方法時(shí)使用throws聲明拋出異常。語(yǔ)法:

      準(zhǔn)備校招,關(guān)于JAVA 異常,面試看這篇就夠了

      [訪問(wèn)符] <返回類型> 方法名([參數(shù)表列])throws 異常類A [,異常類B,異常類C,……]{ }.

      throws只是拋出異常,還需要進(jìn)行捕獲。如果是Error或者RuntimeException或他們的子類,可以不用throws關(guān)鍵字來(lái)聲明要拋出的異常,編譯仍能通過(guò),運(yùn)行時(shí)系統(tǒng)拋出。

      throws 用來(lái)聲明異常,讓調(diào)用者只知道該功能可能出現(xiàn)的問(wèn)題,可以給出預(yù)先的處理方式;throw拋出具體的問(wèn)題對(duì)象,執(zhí)行到throw,功能就已經(jīng)結(jié)束了,跳轉(zhuǎn)到調(diào)用者,并將具體的問(wèn)題對(duì)象拋給調(diào)用者。也就是說(shuō) throw 語(yǔ)句獨(dú)立存在時(shí),下面不要定義其他語(yǔ)句,因?yàn)閳?zhí)行不到。

      throws表示出現(xiàn)異常的一種可能性,并不一定會(huì)發(fā)生這些異常;throw 則是拋出了異常,執(zhí)行throw則一定拋出了某種異常對(duì)象。

      兩者都是消極處理異常的方式,只是拋出或者可能拋出異常,但是不會(huì)由函數(shù)去處理異常,真正的處理異常由函數(shù)的上層調(diào)用處理。

      關(guān)于異常的一些其他編碼經(jīng)驗(yàn):

      如果面試問(wèn)關(guān)于異常,平常開發(fā)中有哪些經(jīng)驗(yàn),要怎么回答?

      [x] 一個(gè)方法被覆蓋時(shí),覆蓋它的方法必須拋出相同的異常或異常的子類。如果父類拋出多個(gè)異常,則覆蓋方法必須拋出那些異常的一個(gè)子集,不能拋出新異常。

      [x] 提倡異常的封裝,可以提供系統(tǒng)的友好性,提高系統(tǒng)的可維護(hù)性,對(duì)異常進(jìn)行分類,解決Java異常機(jī)制缺陷。進(jìn)行異常封裝 。

      class MyException extends Exception{ private List causes = new ArrayList<>(); public MyException(List causes){ this.causes.add((Throwable) causes); } public List getException(){ return causes; } public static void doStuff() throws MyException { List list = new ArrayList<>(); try{ //異常代碼 }catch(Exception e){ list.add(e); } try{ //異常代碼 }catch (Exception e){ list.add(e); } if (list.size() > 0) throw new MyException(list); } }

      [x] 異常只為異常服務(wù),只針對(duì)異常的情況才使用異常,異常應(yīng)該只用于異常的情況下;它們永遠(yuǎn)不應(yīng)該用于正常的控制流。即異常塊里不添加邏輯,添加邏輯會(huì)造成異常判斷降低了系統(tǒng)性能,降低了代碼可讀性,隱藏了運(yùn)行期可能產(chǎn)生的異常.

      [x] 多使用異常,把性能放一邊,異常是主邏輯的例外邏輯,比如 在馬路上走路(主邏輯),突然開過(guò)一輛車,我要避讓(受檢異常,必須處理),繼續(xù)走路,突然一架飛機(jī)從我頭頂飛過(guò)(非受檢異常),我可以選擇走路(不捕捉),也可以選擇職責(zé)其噪音污染(捕捉,主邏輯的補(bǔ)充處理),在繼續(xù)走下去,突然一棵流星砸下類,這是沒(méi)有選擇,屬于錯(cuò)誤,不能做任何處理。

      [x] 不要在構(gòu)造函數(shù)中拋出異常,一個(gè)對(duì)象的創(chuàng)建要經(jīng)過(guò)內(nèi)存分配,靜態(tài)代碼初始化,構(gòu)造函數(shù)執(zhí)行等過(guò)程,一般不在構(gòu)造函數(shù)中拋出異常,是程序員無(wú)法處理的,會(huì)加重上層代碼的編寫者的負(fù)擔(dān),后續(xù)代碼不會(huì)執(zhí)行,違背了里氏替換原則,父類能出現(xiàn)的地方子類就可以出現(xiàn),而且將父類替換為子類也不會(huì)產(chǎn)生任何異常, java的構(gòu)造函數(shù)允許子類的構(gòu)造函數(shù)拋出更廣泛的異常類(正好與類方法的異常機(jī)制相反:子類方法的異常類型必須為父類方法的子類型,覆寫要求),當(dāng)替換時(shí),需要增加catch塊,構(gòu)造函數(shù)沒(méi)有覆寫的概念,只有構(gòu)造函數(shù)之間的引用調(diào)用而已,同時(shí)子類構(gòu)造函數(shù)擴(kuò)展受限。

      [x] 使用Throwsable獲得棧信息,AOP編程可以親松的控制一個(gè)方法調(diào)用那些類,也能控制那些方法允許別調(diào)用,一般來(lái)講切面編程只能控制到方法級(jí)別,不能實(shí)現(xiàn)代碼級(jí)別的植入(Weave),即不同類的不同方法參數(shù)相同調(diào)用相同方法返回不同的值。即要求被調(diào)用者具有識(shí)別調(diào)用者的能力,可以使用Throwable獲得棧信息,然后鑒別調(diào)用者信息。

      package com.liruilong.throwable_demo; /** * @Classname Main * @Description TODO * @Date 2021/6/22 2:31 * @Created Li Ruilong */ public class Main { public static void main(String[] args) { Invoker.m1(); Invoker.m2(); } } class Foo{ public static boolean m(){ // 堆棧跟蹤中的一個(gè)元素,由Throwable.getStackTrace()返回。 每個(gè)元素表示單個(gè)堆棧幀。 // 堆棧頂部除堆棧之外的所有堆棧都表示方法調(diào)用。 堆棧頂部的幀表示生成堆棧跟蹤的執(zhí)行點(diǎn)。 // 通常,這是創(chuàng)建與堆棧跟蹤相對(duì)應(yīng)的throwable的點(diǎn)。 //取得當(dāng)前棧信息 StackTraceElement [] stackTraceElements = new Throwable().getStackTrace(); //檢查是否是m1方法調(diào)用 for(StackTraceElement st: stackTraceElements){ System.out.println(st); if(st.getMethodName().equals("m1")) return true; } return false; //throw new RuntimeException("除m1方法外,該方法不允許其他方法調(diào)用"); } } class Invoker{ //該方法打印true public static void m1(){ System.out.println(Foo.m()); } //該方法打印false public static void m2(){ System.out.println(Foo.m()); } }

      [x] API設(shè)計(jì)中,對(duì)可恢復(fù)的情況使用受檢異常,對(duì)編程錯(cuò)誤使用運(yùn)行時(shí)異常,如果期望調(diào)用者能夠適當(dāng)?shù)鼗謴?fù),對(duì)于這種情況就應(yīng)該使用受檢異常。通過(guò)拋出受檢的異常,強(qiáng)迫調(diào)用者在一個(gè)catch子句中處理該異常,或者將它傳播出去。用運(yùn)行時(shí)異常來(lái)表明編程錯(cuò)誤。你實(shí)現(xiàn)的所有未受檢的拋出結(jié)構(gòu)都應(yīng)該是RuntimeException的子類(直接的或者間接的),

      [x] 避免不必要地使用受檢異常,受檢異常可以提升程序的可讀性;如果過(guò)度使用,將會(huì)使API使用起來(lái)非常痛苦。如果調(diào)用者無(wú)法恢復(fù)失敗,就應(yīng)該拋出未受檢異常。如果可以恢復(fù),并且想要迫使調(diào)用者處理異常的條件,首選應(yīng)該返回一個(gè)optional值。當(dāng)且僅當(dāng)萬(wàn)一失敗時(shí),這些無(wú)法提供足夠的信息,才應(yīng)該拋出受檢異常。

      [x] 優(yōu)先使用標(biāo)準(zhǔn)的異常,重用標(biāo)準(zhǔn)的異常有多個(gè)好處:

      [x] 它使API更易于學(xué)習(xí)和使用,因?yàn)樗c程序員已經(jīng)熟悉的習(xí)慣用法一致。最主要的好處。

      [x] 對(duì)于用到這些API的程序而言,·它們的可讀性會(huì)更好,因?yàn)樗鼈儾粫?huì)出現(xiàn)很多程序員不熟悉的異常。

      [x] 異常類越少,意味著內(nèi)存占用(footprint)就越小,裝載這些類的時(shí)間開銷也越少。最不重要的一點(diǎn)。

      不要直接重用:Exception、 RuntimeException、 Throwable或者Error。對(duì)待"這些類要像對(duì)待抽象類一樣。你無(wú)法可靠地測(cè)試這些異常,因?yàn)樗鼈兪且粋€(gè)方法可能拋出的其他異常的超類。

      [x] 拋出與抽象對(duì)應(yīng)的異常

      [x] 每個(gè)方法拋出的所有異常都要建立文檔,使用Javadoc的@throws標(biāo)簽記錄下一個(gè)方法可能拋出的每個(gè)未受檢異常,但是不要使用throws關(guān)鍵字將未受檢的異常包含在方法的聲明中。如果一個(gè)類中的許多方法出于同樣的原因而拋出同一個(gè)異常,在該類的文檔注釋中對(duì)這個(gè)異常建立文檔,這是可以接受的,而不是為每個(gè)方法單獨(dú)建立文檔。

      [x] 努力使失敗保持原子性,作為方法規(guī)范的一部分,產(chǎn)生的任何異常都應(yīng)該讓對(duì)象保持在調(diào)用該方法之前的狀態(tài)。如果違反這條規(guī)則, API文檔就應(yīng)該清楚地指明對(duì)象將會(huì)處于什么樣的狀態(tài).

      [x] 不要忽略異常忽略一個(gè)異常很容易,空的catch塊會(huì)使異常達(dá)不到應(yīng)有的目的.如果選擇忽略異常, catch塊中應(yīng)該包含注釋,說(shuō)明為什么可以這么做,并且變量應(yīng)該命名為ignored:

      Java JVM

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:maven基本使用-個(gè)人手稿版
      下一篇:[跟著官方文檔學(xué)JUnit5][六][WritingTests][學(xué)習(xí)筆記](méi)
      相關(guān)文章
      亚洲AV色香蕉一区二区| 无码不卡亚洲成?人片| 中文字幕久久亚洲一区 | 亚洲AV日韩AV高潮无码专区| 曰韩亚洲av人人夜夜澡人人爽| 国产成人综合亚洲绿色| WWW亚洲色大成网络.COM| 国产精品久久久久久亚洲影视| 欧美亚洲精品一区二区| 亚洲aⅴ天堂av天堂无码麻豆 | 亚洲国产无套无码av电影| 亚洲精品自在在线观看| 亚洲国产精品SSS在线观看AV| 亚洲AV综合色区无码一区| 亚洲AV成人片色在线观看| 少妇中文字幕乱码亚洲影视| 7777久久亚洲中文字幕蜜桃| 91在线亚洲精品专区| 久久精品蜜芽亚洲国产AV| 亚洲啪啪免费视频| 亚洲一本一道一区二区三区| 亚洲av永久无码精品网址| 亚洲国产精品丝袜在线观看| 国产a v无码专区亚洲av| 亚洲乳大丰满中文字幕| 亚洲AV无码一区二区三区DV| 亚洲网址在线观看你懂的| 亚洲性色成人av天堂| 在线aⅴ亚洲中文字幕| 老子影院午夜伦不卡亚洲| 亚洲区小说区图片区| 亚洲精品无码久久久久| 久久亚洲国产精品五月天| 亚洲高清日韩精品第一区| 亚洲乱码一二三四区乱码| 亚洲AV无码一区二区三区电影| 亚洲欧洲中文日韩av乱码| 亚洲s色大片在线观看| 亚洲精品在线不卡| 亚洲乱码国产乱码精华| 亚洲国产精品狼友中文久久久|