全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Java 常用类解析:java异常机制,异常栈,异常处理方式,异常链,异常丢失详解

1、java标准异常概述

Throwable表示任何可以作为异常被抛出的类,有两个子类Error和Exception。从这两个类的源代码中可以看出,这两个类并没有添加新的方法,Throwable提供了所以方法的实现。Error表示编译时和系统错误。Exception是可以被抛出的异常类。RuntimeException继承自Exception(如NullPointerException),表示运行时异常,JVM会自动抛出.

2、自定义异常类

自定义异常类方法: 通过继承Throwable或Exception。异常类的所有实现都是基类Throwable实现的,所以构造自定义异常类完全可以参考Exception和Error类。我们只要添加上自定义异常类的构造方法就可以了

<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、通过获取栈轨迹中的元素数组来显示异常抛出的轨迹 
   for (StackTraceElement ste : e.getStackTrace()) 
    System.out.println(ste.getMethodName()); 
   //2、直接将异常栈信息输出至标准错误流或标准输出流 
   e.printStackTrace();//输出到标准错误流 
   e.printStackTrace(System.err); 
   e.printStackTrace(System.out); 
   //3、将异常信息输出到文件中 
   //e.printStackTrace(new PrintStream("file/exception.txt")); 
   //4、重新抛出异常,如果直接抛出那么栈路径是完整的,如果用fillInStackTrace() 
   //那么将会从这个方法(当前是h()方法)作为异常发生的原点。 
   //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> 

运行结果:

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函数被调用,然后是调用h函数,再g函数、f函数,f函数抛出异常,并在h函数捕获,这时将依次从栈顶到栈底输出异常栈路径。

4、异常链

有时候我们会捕获一个异常后在抛出另一个异常,如下代码所示:

<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> 

运行结果:

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)

从结果中我们可以看出,异常栈变小了。也就是说丢失了最原始的异常信息。怎样保存最原始的异常信息呢?Throwable类中有个Throwable  cause属性,表示原始异常。通过接收cause参数的构造器可以把原始异常传递给新异常,或者通过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> 

 结果:

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

从结果中看出当获取到“重新抛出异常2的时候,同时可以输出原始异常“重新抛出的异常1“和原始异常”自定义异常,这就是异常链。

5、finally的使用

finally子句总是执行的,通常用来做一些清理工作,如关闭文件,关闭连接等

下面举几个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> 

分析:如果调用in = new BufferedReader(new FileReader(filePath));时发生异常,这时是一个文件路径不存在的异常,也就是说并没有打开文件,这时将会直接跳到catch块,而不会执行try...finally块(并不是finally子句)里面的语句in.close();此时不需要关闭文件。

再看一个例子,会导致异常的丢失

<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();//此时捕获g方法抛出的异常,f方法抛出的异常丢失了 
   } 
  } catch (MyException e) { 
   System.out.println(e); 
  } 
 
 } 
} 
</span> 

结果:mine.util.exception.MyException: 异常2

此时异常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会丢失所以抛出的异常 
   return; 
  } 
 
 } 
} 
</span> 

6、异常的限制

(1)当覆盖方法时,只能抛出在基类方法的异常说明里列出的那些异常,有些基类的方法声明抛出异常其实并没有抛出异常,这是因为可能在其子类的覆盖方法中会抛出异常

(2)构造器可以抛出任何异常而不必理会基类构造器所抛出的异常,派生类构造器异常说明必须包含基类构造器异常说明,因为构造派生类对象时会调用基类构造器。此外,派生类构造器不能捕获基类构造器抛出的异常。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# Java  # 常用类解析  # java异常机制  # 异常栈  # 异常处理方式  # 异常链  # 异常丢失详解  # 抛出  # 自定义  # 子句  # 将会  # 子类  # 这两个  # 可以看出  # 派生类  # 丢失了  # 最原始  # 都是  # 是一个  # 也就是说  # 几个  # 有个  # 不需要  # 这就是  # 并在  # 能在  # 可以通过 


相关文章: 建站之星后台密码遗忘?如何快速找回?  c# F# 的 MailboxProcessor 和 C# 的 Actor 模型  香港网站服务器数量如何影响SEO优化效果?  官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站  建站之星如何配置系统实现高效建站?  网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  建站主机与虚拟主机有何区别?如何选择最优方案?  网站制作需要会哪些技术,建立一个网站要花费多少?  山东网站制作公司有哪些,山东大源集团官网?  清除minerd进程的简单方法  5种Android数据存储方式汇总  建站之星如何保障用户数据免受黑客入侵?  如何快速搭建高效可靠的建站解决方案?  深圳网站制作费用多少钱,读秀,深圳文献港这样的网站很多只提供网上试读,但有些人只要提供试读的文章就能全篇下载,这个是怎么弄的?  湖北网站制作公司有哪些,湖北清能集团官网?  如何用景安虚拟主机手机版绑定域名建站?  如何撰写建站申请书?关键要点有哪些?  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  ,如何利用word制作宣传手册?  如何在阿里云购买域名并搭建网站?  山东云建站价格为何差异显著?  建站之星免费模板:自助建站系统与智能响应式一键生成  岳西云建站教程与模板下载_一站式快速建站系统操作指南  哈尔滨网站建设策划,哈尔滨电工证查询网站?  c# 在高并发下使用反射发射(Reflection.Emit)的性能  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  如何选择高性价比服务器搭建个人网站?  建站之星安装模板失败:服务器环境不兼容?  seo网站制作优化,网站SEO优化步骤有哪些?  如何通过FTP空间快速搭建安全高效网站?  如何在云虚拟主机上快速搭建个人网站?  内部网站制作流程,如何建立公司内部网站?  制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?  如何通过可视化优化提升建站效果?  C#如何在一个XML文件中查找并替换文本内容  外贸公司网站制作哪家好,maersk船公司官网?  如何在服务器上配置二级域名建站?  如何在云主机上快速搭建网站?  天河区网站制作公司,广州天河区如何办理身份证?需要什么资料有预约的网站吗?  网站制作知乎推荐,想做自己的网站用什么工具比较好?  建站DNS解析失败?如何正确配置域名服务器?  如何用IIS7快速搭建并优化网站站点?  建站之星后台管理:高效配置与模板优化提升用户体验  高性能网站服务器部署指南:稳定运行与安全配置优化方案  定制建站流程解析:需求评估与SEO优化功能开发指南  如何在IIS中新建站点并配置端口与IP地址?  如何自定义建站之星模板颜色并下载新样式?  微信小程序 input输入框控件详解及实例(多种示例) 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。