欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

一文帶你快速讀懂Java中的異常

這篇文章給大家介紹一文帶你快速讀懂Java中的異常,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

葉縣ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書合作)期待與您的合作!

什么是異常?

異常是Java語言中的一部分,它代表程序中由各種原因引起的“不正?!币蛩?。 那么在程序中什么樣的情況才算不正常呢? 我認為可以這樣定義:如果出現(xiàn)了這么一種情況,它打斷了程序期望的執(zhí)行流程,改變了控制流的方向(包括讓JVM停掉),那么就可以認為發(fā)生了不正常情況,也就是引發(fā)了異常。舉個例子顯而易見的例子:

FileOutputStream out = null; 
try { 
  out = new FileOutputStream("abc.text"); 
  out.write(1); 
  System.out.println("寫入成功"); 
} catch (FileNotFoundException e) { 
   
  System.out.println("要寫入的文件不存在"); 
  e.printStackTrace(); 
   
} catch (IOException e) { 
   
  System.out.println("發(fā)生了IO錯誤"); 
  e.printStackTrace(); 
   
}finally{ 
  if(out != null){ 
    try { 
      out.close(); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
  } 
} 

我調用FileOutputStream.write(int)方法期望向一個文件寫入一個字節(jié)的數(shù)據(jù),如果在寫入時發(fā)生了IO錯誤, 那么就發(fā)生了“不正常情況”,也就是拋出IOException,進而程序的控制流發(fā)生了改變,本來如果寫入成功的話, 會執(zhí)行FileOutputStream.write(int)下一句代碼, 現(xiàn)在發(fā)生了異常, 那么程序要跳到IOException對應的catch塊中,去處理這個異常情況。

異常體系和分類

Java以面向對象的方式來管理異常情況,也就是說,Java程序執(zhí)行時遇到的各種問題都被封裝成了對象,并且這些對象之間具有繼承關系。java中的讓人不爽的“不正常情況”可以分為兩種,一種叫做Error,一種是在程序中到處可見的Exception,而他們都繼承自Throwable。Exception又分為編譯時受檢查異常(Checked Exception)和運行時異常(RuntimeException)。如下圖所示(該圖片來源于網(wǎng)絡):

一般情況下,Error代表虛擬機在執(zhí)行程序時遇到嚴重問題,不能再回復執(zhí)行了,這屬于重大事故,虛擬機要掛掉的,一句話概括就是“這病沒得治,等死就行了”。那么打開JDK的文檔,列舉幾種Error:

VirtualMachineError: 當 Java 虛擬機崩潰或用盡了它繼續(xù)操作所需的資源時,拋出該錯誤。

ClassFormatError:當 Java 虛擬機試圖讀取類文件并確定該文件存在格式錯誤或無法解釋為類文件時,拋出該錯誤。

NoClassDefFoundError:當 Java 虛擬機或 ClassLoader 實例試圖在類的定義中加載,但無法找到該類的定義時,拋出此異常。

而相對于Error,Exception是java程序中遇到的“不那么嚴重”的問題,這種問題是可以處理的,當處理了這個問題后,程序還可以繼續(xù)執(zhí)行。一句話概括,“這是病,得治,這病是可以治好的”。

Exception就比較常見了,隨便舉幾個例子。當創(chuàng)建文件輸入流時, 發(fā)現(xiàn)文件不存在,那么拋出FileNotFoundException,但是異??梢蕴幚?,沒法讀文件,并不會在很大長度上影響整個程序的執(zhí)行,畢竟不能讀文件,程序還可以執(zhí)行其他邏輯。下面舉一個趣味性的示例:

public class Travel { 
  private static int power = 100; 
  private static boolean bridgeIsOk = true; 
  public static void main(String[] args) { 
    //描述一下坐火車旅游的過程 
    System.out.println("從濟南出發(fā), 到北京旅游"); 
    System.out.println("列車開到德州"); 
    //中途給媽媽打個電話 
    try{ 
      telToMom(); 
    }catch(BatteryDiedException e){ 
      System.out.println("換一塊電池, 繼續(xù)旅程"); 
    } 
    //橋斷了 
    if(!bridgeIsOk){ 
      System.out.println("旅程結束"); 
      throw new BridgeBreakError("橋斷了,列車停止運行"); 
    } 
    System.out.println("到北京站,下車"); 
    //下雨了 
    try{ 
      throw new RainException("下雨了"); 
    }catch(RainException e){ 
      System.out.println("撐起準備的雨傘, 繼續(xù)旅程"); 
    } 
  } 
  private static void telToMom() throws BatteryDiedException{ 
    if(power == 0){ //手機電量為0 
      System.out.println("手機沒電了"); 
      throw new BatteryDiedException("手機沒電了"); 
    } 
    System.out.println("給媽媽打電話"); 
  } 
  static class BatteryDiedException extends Exception{ 
    public BatteryDiedException(String msg){ 
      super(msg); 
    } 
  } 
  static class BridgeBreakError extends Error{ 
    public BridgeBreakError(String msg){ 
      super(msg); 
    } 
  } 
  static class RainException extends Exception{ 
    public RainException(String msg){ 
      super(msg); 
    } 
  } 
} 

上面的代碼描述了一次旅行, 如果在旅途中給媽媽打電話,發(fā)現(xiàn)手機沒電了, 拋出BatteryDiedException,但是這種異常是可以應付的,直接換一塊準備的備用電池就OK了,下了車之后,天下雨了,拋出RainException,這種異常也可以應付,因為提前準備了雨傘。這兩種情況都是可以恢復的,遇到之后,只需做一定的處理,旅程還能繼續(xù)。如果在途中遇到橋斷裂的情況,那么列車必須停止運行,這次旅行就泡湯了,也就是說已經不能從這種惡劣情況中恢復過來,所以直接拋出BridgeBreakError。

編譯時受檢查異常和運行時異常

那么再說一下編譯時受檢查異常和運行時異常?;仡櫼幌庐惓5亩x:程序在執(zhí)行時遇到的不正常情況。那么既然是運行時遇到的問題,怎么還有一個編譯時受檢查異常呢?其實編譯時根本不會發(fā)生異常,只會在語法錯誤的情況下編譯失敗,但是這和異常是不相關的概念。異常只是運行時的行為。那么編譯時受檢查異常又是一個什么概念呢?要理解受檢查異常存在的意義,那么必須明確編碼者所處的位置,也可以說編碼者的角色, 即:我是功能的具體實現(xiàn)者, 還是功能的使用者,也可以說,我是方法的編寫者還是已有方法的調用者。如果我是方法的實現(xiàn)者,我在編碼時發(fā)現(xiàn)可能會出現(xiàn)異常,那么首先我要明確,這個可能出現(xiàn)的異常我能不能自己處理,如果能自己處理, 那么就在方法內部自己處理掉,如果不能自己處理,那么通知方法的調用者處理。舉例說明:

public static Class<&#63;> forName(String className)  
      throws ClassNotFoundException { 
  return forName0(className, true, ClassLoader.getCallerClassLoader()); 
} 

上面的代碼是JDK中Class類的forName()方法。作為JDK類庫的作者,在寫這個方法的時候,可能會出現(xiàn)異常, 也就是類加載不到。但是他不知道如何處理這個情況,因為他不知道調用這個方法的用戶是加載的什么類,可能是一個非常重要的類, 加載不成的話程序就只能停掉,也可能是一個不那么重要的類,加載不到也沒有嚴重影響。所以,如何處理這個情況,必須是由用戶決定。方法后面的throws ClassNotFoundException的意義是:這個方法可能出現(xiàn)ClassNotFoundException,你如果調用了這個方法,那么必須做好防范措施(用try-catch處理這個異常,或者再向上拋出)。如果站在方法使用者的角度,我調用這個方法,如果出現(xiàn)異常,我可以提前準備好解決方案:

try { 
  Class clazz = Class.forName("com.bjpowernode.Person"); 
} catch (ClassNotFoundException e) { 
   
  System.out.println("Person類加載失敗"); 
  System.exit(0); 
  e.printStackTrace(); 
}

 Person類是一個非常中要的類,必須加載成功才能繼續(xù)執(zhí)行。如果加載失敗, 只能讓程序停掉,并且打印出日志。這樣的話,程序員可以在其他地方確保這個類必須是可加載的。
所以,可以把編譯時受檢查異??醋鲆环N錯誤預警機制:這個錯誤可能發(fā)生, 但也可能不發(fā)生,但是如果你想使用這個功能的話,必須做好處理措施,可以使用try-catch處理異常, 也可以拋向更高層。

說完了編譯時受檢查異常,那么在談運行時異常, 所有運行時異常的頂層父類都是RuntimeException, RuntimeException也是繼承自Exception的。下面是JDK文檔中對運行時異常的解釋。

1.RuntimeException 是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類。   

3.可能在執(zhí)行方法期間拋出但未被捕獲的 RuntimeException 的任何子類都無需在 throws 子句中進行聲明。  

也就是說, 如果你在方法中拋出了運行時異?;蛘咂渥宇?,那么可以不必在方法上聲明會拋出異常,所以調用這個方法的調用者也就不必在使用的時候做預防措施。那么在異常發(fā)生的時候,由于沒有處理措施,那么只能讓虛擬機停掉,也就是說這種異常一般不需要提前預防。那么什么時候使用運行時異常呢?可以這樣認為:如果發(fā)生了這樣一個異常時,讓程序停掉是合理的,那么這種情況就適合使用運行時異常。

還是以上面旅行的例子做一個說明。如果手機在旅途沒電了,那么預防這種情況是有意義的,因為換了電池之后還可以繼續(xù)旅行;突然下雨這種情況也可預防,并且預防這種情況是有意義的,因為打起傘來同樣可以繼續(xù)前進。那么,如果如果在旅途中病了,并且病的還很厲害,那么再預防這種情況對整個旅程來說就沒有什么意義了,因為旅程必須終止(看病要緊)。所以直接拋出一個運行時異常讓旅程終止。如下:

private static boolean isSick = true; 
public static void main(String[] args) { 
  if(isSick){ 
    System.out.println("生病了,旅途中止"); 
    throw new SickException("病了"); 
  } 
} 
private static class SickException extends RuntimeException{ 
  public SickException(String msg){ 
    super(msg); 
  } 
} 

 一般來說,運行時異常非常適合處理編程錯誤,那么什么是編程錯誤呢?可以認為是程序員寫的代碼有問題,必須修改程序才能解決問題??匆幌翵DK中的兩個RuntimeException的例子。

IllegalArgumentException:如果用戶(方法的調用者)傳遞的參數(shù)不對,那么就會拋出非法參數(shù)異常,然后讓程序停掉,如果想讓程序正確的運行,必須修改調用方式,傳遞一個正確的參數(shù)。如下:

public static void main(String[] args) { 
  caculateSalary(3); 
} 
 
/** 
 * 計算一個月的薪資 
 * @param month 月份 
 */ 
public static void caculateSalary(int month){ 
   
  //如果參數(shù)錯誤, 拋出非法參數(shù)異常 
  if(month < 1 || month > 12){ 
    throw new IllegalArgumentException(); 
  } 
} 
 
private static void caculateSalaryInner(int month){ 
  //計算薪資 ... 
} 

NullPointerException:如果調用一個方法的對象為null,那么在調用的時候會拋出空指針異常。如果要避免的話,就要修改程序,確保調用方法的對象不為空。

ClassCastException:如果在進行類型轉換時,指定了錯誤的目標類型,那么會拋出類型轉換異常。如果要避免的話,要修改代碼,以確保指定了正確的要轉換的目標類型。

雖然RuntimeException一般用于表示編程錯誤,在拋出運行時異常時讓程序停掉,對代碼做一定的改正以讓程序可以再次正確運行, 但是要注意到,運行時異常是可以捕獲的,捕獲之后做出處理后,程序可以恢復執(zhí)行:

public static void main(String[] args) { 
  doSomething(); 
} 
public static void doSomething(){ 
  Object obj = null; 
  try { //運行時異常也是可以捕獲的 
    obj.toString(); 
  } catch (RuntimeException e) { 
    System.out.println("拋出了運行時異常, 異常的具體類型:" + e.getClass().getName()); 
  } 
} 

打印結果為: 拋出了運行時異常, 異常的具體類型:java.lang.NullPointerException

另外,運行時異常也可以在方法上聲明拋出,但是如果方法上聲明的是運行時異常,那么方法的調用者可以選擇處理, 也可以選擇不處理。如果不處理的話,程序會終止,如果捕獲后做出處理,程序可以恢復運行:

public static void main(String[] args) { 
  doSomething();  //不必處理方法聲明拋出的運行時異常 
} 
 
public static void doSomething() throws RuntimeException{ 
   
  throw new RuntimeException(); 
} 

雖然運行時異??梢栽诜椒ㄉ下暶鲯伋?,也可以被捕獲,但是一般情況下我們不會這么做。因為運行時異常一般用于表示編程錯誤,出現(xiàn)異常時讓程序停掉是合理的。對運行時異常進行捕獲和聲明拋出沒有多大的意義。比如捕獲了空指針異常,雖然進行了處理以讓程序不至于崩潰,但是空對象要調用的方法,根本就沒有調用成功,這是不合理的。

如何合理使用異常

上面介紹了異常的定義和分類,也提到了一些異常的使用原則。現(xiàn)在總結一下到底應該如何使用異常:

1 重大的錯誤使用Error。一般Error用于表示系統(tǒng)級別的或虛擬機層面上的錯誤,在編程中很少使用。

2 有必要預防,并且處理后可以讓程序恢復執(zhí)行的情況使用編譯時受檢查異常。

3 編程錯誤使用運行時異常。

4 如果方法自己可以處理異常,那么可以選擇自己處理異常,如果方法不知道如何處理異常,那么拋給高層的方法調用者。

5 方法聲明拋向高層的異常,必須是對高層有意義并且高層能夠理解的異常。

下面再舉一個趣味性的例子。

老板派員工出去執(zhí)行一項任務,在這個過程中有兩個角色,員工是低層被調用者,老板是高層調用者。在這個過程中可能出現(xiàn)這么幾種情況。

1 老板讓員工出去執(zhí)行一項任務, 那么必須得給撥款(沒錢干不成事嘛)。那么如果老板沒給錢,或者給的錢不夠,那么員工可以選擇停止執(zhí)行。這屬于編程錯誤,要求老板必須給足夠的錢才能繼續(xù)運行。這種情況使用運行時異常表示。

2 到了目的地后,要去辦公地點,發(fā)現(xiàn)迷路了(可能方向感不好,轉向了),找不到公交車的站牌了。這個錯誤自己完全可以解決,打個車就可以了。并且不能拋給老板,如果拋給老板,那么就等著被炒魷魚吧。老板每天很忙,他會這樣認為:這員工太操蛋了,這點事都辦不成。所以這是個受檢查異常,并且適合在內部解決。

3 出差在外,加班太辛苦,在干到一半的時候,累病了。這就是比較嚴重的情況了,自己不能很好地解決(得去醫(yī)院)。這也是可以預見的異常,畢竟人都會得病嘛。這也屬于受檢查異常,自己不能解決,得拋向高層(老板)。但是應該怎樣給老板說呢?不能給老板說“老板,我病了”,如果這樣給老板說的話,老板會一頭霧水:“病了去醫(yī)院啊, 我又不是醫(yī)生”。那么怎么給老板說呢?直接告訴老板任務不能完成就行了,當然可以說明為什么不能完成的原因(生病了)。這樣的話,老板就可以做出一些處理,可以另外再拍一個人去交接任務,也可以決定暫停任務。所以,拋向高層的異常,必須是對高層有意義并且高層能夠理解的異常。

下面用代碼描述這個過程:

public class DoWork { 
  public static class Boss{  //老板 
    private Employee emp; //員工對象 
    public Boss(Employee emp){ 
      this.emp = emp; 
    } 
    public void doWork(){  
      try { 
        emp.doWork();  //老板委托員工外出執(zhí)行任務,給員工塊錢的經費 
      } catch (TaskCannotCompleteException e) {  //任務無法完成 
        System.out.println("派出另一個員工去完成任務"); 
      }  
    } 
  } 
  public static class Employee{  //員工 
    //執(zhí)行任務,可能不能完成任務 
    public void doWork(float money) throws TaskCannotCompleteException{ 
      //  
      if(money < ){  //經費太少,無法執(zhí)行任務 
        throw new MoneyNotEnoughException(); 
      } 
      // 
      try { 
        goToWorkPlace(); 
      } catch (CannotFindBusException e) { //在去工作地點時找不到公交車 
        System.out.println("打車去"); 
      } 
      // 
      try { 
        workDayAndNight(); 
      } catch (TiredToSickException e) { //累病了 
        //告訴老板,任務無法完成 
        throw new TaskCannotCompleteException(); 
      } 
    } 
    //在去工作地點時可能找不到公交車 
    private void goToWorkPlace() throws CannotFindBusException{ 
      //throw new CannotFindBusException(); 
    } 
    //沒天沒夜的干活, 可能會累病 
    private void workDayAndNight() throws TiredToSickException{ 
      //throw new TiredToSickException(); 
    } 
  } 
  //找不到公交車異常 
  public static class CannotFindBusException extends Exception{} 
  //經費不足異常 
  public static class MoneyNotEnoughException extends RuntimeException{} 
  //累病異常 
  public static class TiredToSickException extends Exception{} 
  //任務無法完成異常 
  public static class TaskCannotCompleteException extends Exception{} 
  public static void main(String[] args) { 
    Boss boss = new Boss(new Employee()); 
    boss.doWork(); 
  } 
} 

關于一文帶你快速讀懂Java中的異常就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

當前標題:一文帶你快速讀懂Java中的異常
URL網(wǎng)址:http://chinadenli.net/article38/jgijsp.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供App設計、網(wǎng)站設計、網(wǎng)站策劃、響應式網(wǎng)站、品牌網(wǎng)站設計、網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設
亚洲欧美日本视频一区二区| 免费啪视频免费欧美亚洲 | 国产一区二区三区av在线| 97人妻精品一区二区三区免| 中文字幕乱码亚洲三区| 视频一区二区 国产精品| 不卡一区二区高清视频| 性欧美唯美尤物另类视频| 隔壁的日本人妻中文字幕版| 亚洲综合激情另类专区老铁性| 久久亚洲精品成人国产| 91亚洲人人在字幕国产| 99久热只有精品视频最新| 亚洲国产精品久久网午夜| 人妻亚洲一区二区三区| 免费大片黄在线观看国语| 久久热九九这里只有精品| 91老熟妇嗷嗷叫太91| 欧美日韩国产精品黄片| 精品欧美在线观看国产| 国产超薄黑色肉色丝袜| 精品人妻一区二区三区免费| 观看日韩精品在线视频| 好吊视频一区二区在线| 亚洲a码一区二区三区| 国产黄色高清内射熟女视频| 日本高清一区免费不卡| 中文字幕一区二区久久综合| 欧美综合色婷婷欧美激情| 亚洲一区在线观看蜜桃| 91欧美一区二区三区成人| 日韩精品日韩激情日韩综合| 日韩欧美中文字幕人妻| 国产一区日韩二区欧美| 夜夜嗨激情五月天精品| 欧美一区二区三区在线播放| 国产一区日韩二区欧美| 日本婷婷色大香蕉视频在线观看| 丰满熟女少妇一区二区三区| 国产又大又硬又粗又黄| 欧美小黄片在线一级观看|