欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 常用類解析:java異常機(jī)制,異常棧,異常處理方式,異常鏈,異常丟失詳解

 更新時(shí)間:2017年03月14日 08:37:24   投稿:lqh  
這篇文章主要介紹了Java 常用類解析:java異常機(jī)制,異常棧,異常處理方式,異常鏈,異常丟失詳解的相關(guān)資料,需要的朋友可以參考下

1、java標(biāo)準(zhǔn)異常概述

Throwable表示任何可以作為異常被拋出的類,有兩個(gè)子類Error和Exception。從這兩個(gè)類的源代碼中可以看出,這兩個(gè)類并沒有添加新的方法,Throwable提供了所以方法的實(shí)現(xiàn)。Error表示編譯時(shí)和系統(tǒng)錯(cuò)誤。Exception是可以被拋出的異常類。RuntimeException繼承自Exception(如NullPointerException),表示運(yùn)行時(shí)異常,JVM會(huì)自動(dòng)拋出.

2、自定義異常類

自定義異常類方法: 通過繼承Throwable或Exception。異常類的所有實(shí)現(xiàn)都是基類Throwable實(shí)現(xiàn)的,所以構(gòu)造自定義異常類完全可以參考Exception和Error類。我們只要添加上自定義異常類的構(gòu)造方法就可以了

<span style="font-size:16px;">package demo.others; 
 
/** 
 * 自定義異常類方法 
 * 1、通過繼承Throwable 
 * 2、通過繼承Exception 
 * 
 * @author Touch 
 */ 
public class MyExceptionDemo extends Exception { 
 
 private static final long serialVersionUID = 1L; 
 
 public MyExceptionDemo() { 
  super(); 
 } 
 
 public MyExceptionDemo(String message) { 
  super(message); 
 } 
 
 public MyExceptionDemo(String message, Throwable cause) { 
  super(message, cause); 
 } 
 
 public MyExceptionDemo(Throwable cause) { 
  super(cause); 
 } 
} 
</span> 

 3、異常棧及異常處理方式

可以通過try、catch來捕獲異常。捕獲到的異常。下面的示例演示了幾種常用異常處理方式

<span style="font-size:16px;">package demo.others; 
 
import mine.util.exception.MyException; 
 
public class ExceptionDemo1 { 
 public void f() throws MyException { 
  throw new MyException("自定義異常"); 
 } 
 
 public void g() throws MyException { 
  f(); 
 } 
 
 public void h() throws MyException { 
  try { 
   g(); 
  } catch (MyException e) { 
   //1、通過獲取棧軌跡中的元素?cái)?shù)組來顯示異常拋出的軌跡 
   for (StackTraceElement ste : e.getStackTrace()) 
    System.out.println(ste.getMethodName()); 
   //2、直接將異常棧信息輸出至標(biāo)準(zhǔn)錯(cuò)誤流或標(biāo)準(zhǔn)輸出流 
   e.printStackTrace();//輸出到標(biāo)準(zhǔn)錯(cuò)誤流 
   e.printStackTrace(System.err); 
   e.printStackTrace(System.out); 
   //3、將異常信息輸出到文件中 
   //e.printStackTrace(new PrintStream("file/exception.txt")); 
   //4、重新拋出異常,如果直接拋出那么棧路徑是完整的,如果用fillInStackTrace() 
   //那么將會(huì)從這個(gè)方法(當(dāng)前是h()方法)作為異常發(fā)生的原點(diǎn)。 
   //throw e; 
   throw (MyException)e.fillInStackTrace(); 
  } 
 } 
 public static void main(String[] args) { 
   try { 
    new ExceptionDemo1().h(); 
   } catch (MyException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
   } 
 } 
} 
</span> 

運(yùn)行結(jié)果:

f
g
h
main
mine.util.exception.MyException: 自定義異常
 at demo.others.ExceptionDemo1.f(ExceptionDemo1.Java:7)
 at demo.others.ExceptionDemo1.g(ExceptionDemo1.Java:11)
 at demo.others.ExceptionDemo1.h(ExceptionDemo1.java:16)
 at demo.others.ExceptionDemo1.main(ExceptionDemo1.java:35)
mine.util.exception.MyException: 自定義異常
 at demo.others.ExceptionDemo1.f(ExceptionDemo1.java:7)
 at demo.others.ExceptionDemo1.g(ExceptionDemo1.java:11)
 at demo.others.ExceptionDemo1.h(ExceptionDemo1.java:16)
 at demo.others.ExceptionDemo1.main(ExceptionDemo1.java:35)
mine.util.exception.MyException: 自定義異常
 at demo.others.ExceptionDemo1.f(ExceptionDemo1.java:7)
 at demo.others.ExceptionDemo1.g(ExceptionDemo1.java:11)
 at demo.others.ExceptionDemo1.h(ExceptionDemo1.java:16)
 at demo.others.ExceptionDemo1.main(ExceptionDemo1.java:35)
mine.util.exception.MyException: 自定義異常
 at demo.others.ExceptionDemo1.h(ExceptionDemo1.java:30)
 at demo.others.ExceptionDemo1.main(ExceptionDemo1.java:35)

分析上面的程序,首先main函數(shù)被調(diào)用,然后是調(diào)用h函數(shù),再g函數(shù)、f函數(shù),f函數(shù)拋出異常,并在h函數(shù)捕獲,這時(shí)將依次從棧頂?shù)綏5纵敵霎惓B窂健?br />

4、異常鏈

有時(shí)候我們會(huì)捕獲一個(gè)異常后在拋出另一個(gè)異常,如下代碼所示:

<span style="font-size:16px;">package demo.others; 
 
import java.io.IOException; 
 
import mine.util.exception.MyException; 
 
public class ExceptionDemo2 { 
 public void f() throws MyException { 
  throw new MyException("自定義異常"); 
 } 
 
 public void g() throws Exception { 
  try { 
   f(); 
  } catch (MyException e) { 
   e.printStackTrace(); 
   throw new Exception("重新拋出的異常1"); 
  } 
 } 
 
 public void h() throws IOException { 
  try { 
   g(); 
  } catch (Exception e) { 
   // TODO Auto-generated catch block 
   e.printStackTrace(); 
   throw new IOException("重新拋出異常2"); 
  } 
 } 
 public static void main(String[] args) { 
   try { 
    new ExceptionDemo2().h(); 
   } catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
   } 
 } 
} 
</span> 

運(yùn)行結(jié)果:

mine.util.exception.MyException: 自定義異常
 at demo.others.ExceptionDemo2.f(ExceptionDemo2.java:9)
 at demo.others.ExceptionDemo2.g(ExceptionDemo2.java:14)
 at demo.others.ExceptionDemo2.h(ExceptionDemo2.java:23)
 at demo.others.ExceptionDemo2.main(ExceptionDemo2.java:32)
java.lang.Exception: 重新拋出的異常1
 at demo.others.ExceptionDemo2.g(ExceptionDemo2.java:17)
 at demo.others.ExceptionDemo2.h(ExceptionDemo2.java:23)
 at demo.others.ExceptionDemo2.main(ExceptionDemo2.java:32)
java.io.IOException: 重新拋出異常2
 at demo.others.ExceptionDemo2.h(ExceptionDemo2.java:27)
 at demo.others.ExceptionDemo2.main(ExceptionDemo2.java:32)

從結(jié)果中我們可以看出,異常棧變小了。也就是說丟失了最原始的異常信息。怎樣保存最原始的異常信息呢?Throwable類中有個(gè)Throwable  cause屬性,表示原始異常。通過接收cause參數(shù)的構(gòu)造器可以把原始異常傳遞給新異常,或者通過initCause()方法。如下示例:

<span style="font-size:16px;">package demo.others; 
 
import java.io.IOException; 
 
import mine.util.exception.MyException; 
 
public class ExceptionDemo2 { 
 public void f() throws MyException { 
  throw new MyException("自定義異常"); 
 } 
 
 public void g() throws Exception { 
  try { 
   f(); 
  } catch (MyException e) { 
   e.printStackTrace(); 
   throw new Exception("重新拋出的異常1",e); 
  } 
 } 
 
 public void h() throws IOException { 
  try { 
   g(); 
  } catch (Exception e) { 
   // TODO Auto-generated catch block 
   e.printStackTrace(); 
   IOException io=new IOException("重新拋出異常2"); 
   io.initCause(e); 
   throw io; 
  } 
 } 
 public static void main(String[] args) { 
   try { 
    new ExceptionDemo2().h(); 
   } catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
   } 
 } 
} 
</span> 

 結(jié)果:

mine.util.exception.MyException: 自定義異常
 at demo.others.ExceptionDemo2.f(ExceptionDemo2.java:9)
 at demo.others.ExceptionDemo2.g(ExceptionDemo2.java:14)
 at demo.others.ExceptionDemo2.h(ExceptionDemo2.java:23)
 at demo.others.ExceptionDemo2.main(ExceptionDemo2.java:34)
java.lang.Exception: 重新拋出的異常1
 at demo.others.ExceptionDemo2.g(ExceptionDemo2.java:17)
 at demo.others.ExceptionDemo2.h(ExceptionDemo2.java:23)
 at demo.others.ExceptionDemo2.main(ExceptionDemo2.java:34)
Caused by: mine.util.exception.MyException: 自定義異常
 at demo.others.ExceptionDemo2.f(ExceptionDemo2.java:9)
 at demo.others.ExceptionDemo2.g(ExceptionDemo2.java:14)
 ... 2 more
java.io.IOException: 重新拋出異常2
 at demo.others.ExceptionDemo2.h(ExceptionDemo2.java:27)
 at demo.others.ExceptionDemo2.main(ExceptionDemo2.java:34)
Caused by: java.lang.Exception: 重新拋出的異常1
 at demo.others.ExceptionDemo2.g(ExceptionDemo2.java:17)
 at demo.others.ExceptionDemo2.h(ExceptionDemo2.java:23)
 ... 1 more
Caused by: mine.util.exception.MyException: 自定義異常
 at demo.others.ExceptionDemo2.f(ExceptionDemo2.java:9)
 at demo.others.ExceptionDemo2.g(ExceptionDemo2.java:14)
 ... 2 more

從結(jié)果中看出當(dāng)獲取到“重新拋出異常2的時(shí)候,同時(shí)可以輸出原始異常“重新拋出的異常1“和原始異?!弊远x異常,這就是異常鏈。

5、finally的使用

finally子句總是執(zhí)行的,通常用來做一些清理工作,如關(guān)閉文件,關(guān)閉連接等

下面舉幾個(gè)finally的例子:

<span style="font-size:16px;">// 讀取指定路徑文本文件 
 public static String read(String filePath) { 
  StringBuilder str = new StringBuilder(); 
  BufferedReader in = null; 
  try { 
   in = new BufferedReader(new FileReader(filePath)); 
   String s; 
   try { 
    while ((s = in.readLine()) != null) 
     str.append(s + '\n'); 
   } finally { 
    in.close(); 
   } 
  } catch (IOException e) { 
   // TODO Auto-generated catch block 
   e.printStackTrace(); 
  } 
  return str.toString(); 
 }</span> 

分析:如果調(diào)用in = new BufferedReader(new FileReader(filePath));時(shí)發(fā)生異常,這時(shí)是一個(gè)文件路徑不存在的異常,也就是說并沒有打開文件,這時(shí)將會(huì)直接跳到catch塊,而不會(huì)執(zhí)行try...finally塊(并不是finally子句)里面的語句in.close();此時(shí)不需要關(guān)閉文件。

再看一個(gè)例子,會(huì)導(dǎo)致異常的丟失

<span style="font-size:16px;">package demo.others; 
 
import mine.util.exception.MyException; 
 
public class ExceptionDemo3 { 
 public void f() throws MyException { 
  throw new MyException("異常1"); 
 } 
 
 public void g() throws MyException { 
  throw new MyException("異常2"); 
 } 
 
 public static void main(String[] args) { 
 
  try { 
   ExceptionDemo3 ex = new ExceptionDemo3(); 
   try { 
    ex.f(); 
   } finally { 
    ex.g();//此時(shí)捕獲g方法拋出的異常,f方法拋出的異常丟失了 
   } 
  } catch (MyException e) { 
   System.out.println(e); 
  } 
 
 } 
} 
</span> 

結(jié)果:mine.util.exception.MyException: 異常2

此時(shí)異常1就丟失了

或者這樣寫:

<span style="font-size:16px;">package demo.others; 
 
import mine.util.exception.MyException; 
 
public class ExceptionDemo3 { 
 
 public void g() throws MyException { 
  throw new MyException("異常2"); 
 } 
 
 public static void main(String[] args) { 
  ExceptionDemo3 ex = new ExceptionDemo3(); 
  try { 
   ex.g(); 
  } finally { 
   //直接return會(huì)丟失所以拋出的異常 
   return; 
  } 
 
 } 
} 
</span> 

6、異常的限制

(1)當(dāng)覆蓋方法時(shí),只能拋出在基類方法的異常說明里列出的那些異常,有些基類的方法聲明拋出異常其實(shí)并沒有拋出異常,這是因?yàn)榭赡茉谄渥宇惖母采w方法中會(huì)拋出異常

(2)構(gòu)造器可以拋出任何異常而不必理會(huì)基類構(gòu)造器所拋出的異常,派生類構(gòu)造器異常說明必須包含基類構(gòu)造器異常說明,因?yàn)闃?gòu)造派生類對(duì)象時(shí)會(huì)調(diào)用基類構(gòu)造器。此外,派生類構(gòu)造器不能捕獲基類構(gòu)造器拋出的異常。

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • SpringBoot設(shè)置默認(rèn)主頁的方法步驟

    SpringBoot設(shè)置默認(rèn)主頁的方法步驟

    這篇文章主要介紹了SpringBoot設(shè)置默認(rèn)主頁的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • springsecurity記住我登錄時(shí)訪問無權(quán)限接口跳轉(zhuǎn)登錄界面的處理方案

    springsecurity記住我登錄時(shí)訪問無權(quán)限接口跳轉(zhuǎn)登錄界面的處理方案

    這篇文章主要介紹了springsecurity記住我登錄時(shí)訪問無權(quán)限接口跳轉(zhuǎn)登錄界面的處理方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-02-02
  • mybatis-plus主鍵生成策略

    mybatis-plus主鍵生成策略

    這篇文章主要介紹了mybatis-plus主鍵生成策略,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Spring-boot原理及spring-boot-starter實(shí)例和代碼

    Spring-boot原理及spring-boot-starter實(shí)例和代碼

    spring-boot的starter是一個(gè)通過maven完成自包含并通過annotation配置使得可被spring上下文發(fā)現(xiàn)并實(shí)例化的一個(gè)可插拔的組件或服務(wù)。這篇文章主要介紹了Spring-boot原理及spring-boot-starter實(shí)例和代碼 ,需要的朋友可以參考下
    2019-06-06
  • SpringBoot依賴管理的源碼解析

    SpringBoot依賴管理的源碼解析

    這篇文章主要介紹了SpringBoot依賴管理的源碼解析,maven提供了一套依賴管理機(jī)制,通過在pom.xml定義坐標(biāo),通過坐標(biāo)從互聯(lián)網(wǎng)的中央倉庫下載依賴的構(gòu)件(jar包),規(guī)范去管理依賴所有構(gòu)件,這就叫依賴管理,需要的朋友可以參考下
    2023-04-04
  • Jenkins如何實(shí)現(xiàn)自動(dòng)打包部署linux

    Jenkins如何實(shí)現(xiàn)自動(dòng)打包部署linux

    這篇文章主要介紹了Jenkins如何實(shí)現(xiàn)自動(dòng)打包部署linux,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • java中BeanUtils.copyProperties的用法(超詳細(xì))

    java中BeanUtils.copyProperties的用法(超詳細(xì))

    本文介紹了BeanUtils.copyProperties()方法的使用,包括其功能、用法、注意事項(xiàng)和示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • 基于SpringBoot加載Mybatis的TypeAlias問題

    基于SpringBoot加載Mybatis的TypeAlias問題

    這篇文章主要介紹了解決SpringBoot加載Mybatis的TypeAlias問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java組件FileUpload上傳文件實(shí)現(xiàn)代碼

    Java組件FileUpload上傳文件實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了Java組件FileUpload上傳文件實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • SpringBoot整合MQTT小結(jié)匯總

    SpringBoot整合MQTT小結(jié)匯總

    MQTT 客戶端是運(yùn)行 MQTT 庫并通過網(wǎng)絡(luò)連接到 MQTT 代理的任何設(shè)備,是一種基于發(fā)布/訂閱(publish/subscribe)模式的“輕量級(jí)”通訊協(xié)議,該協(xié)議構(gòu)建于 TCP/IP 協(xié)議上,由 IBM 于 1999 年發(fā)明,對(duì)SpringBoot整合MQTT相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-01-01

最新評(píng)論