Java异常处理机制

我们平时程序中都遇到过异常处理的问题,今天抽时间总结下java的异常处理机制。

首先我们来看异常的分类:

Error 系统级别的错误: Java 运行时环境出现的错误,不可控。

Exception 是程序级别的错误:编译阶段的错误,可控。

异常结构中的父类 Throwable 类,其下子类 Exception类和 Error 类。我们在程序中可以捕获的是 Exception 的子类异常。

1、异常处理语句: try-catch,如果 try 块捕获到异常,则到 catch 块中处理,否则跳过忽略 catch 块(开发中,一定有解决的办法才写,无法解决就向上抛 throws)。
try{//关键字,只能有一个 try 语句
 可能发生异常的代码片段
}catch(Exception e){//列举代码中可能出现的异常类型,可有多个 catch 语句
 当出现了列举的异常类型后,在这里处理,并有针对性的处理
}
2、良好的编程习惯,在异常捕获机制的最后书写 catch(Exception e)捕获未知的错误(或不需要针对处理的错误)。
3、catch 的捕获是由上至下的,所以不要把父类异常写在子类异常的上面,否则子类异常永远没有机会处理,在 catch 块中可以使用方法获取异常信息:
(1)getMessage()方法:用来得到有关异常事件的信息。
(2)printStackTrace()方法:用来跟踪异常事件发生时执行堆栈的内容。
4、throw 关键字:用于主动抛出一个异常当我们的方法出现错误时,这个错误我们不应该去解决,而是通知调用方法去解决时,会将这个错误告知外界,而告知外界的方式就是 throw 异常(抛出异常) catch 语句中也可抛出异常。 虽然不解决,但要捕获,然后抛出去。
使用环境:
我们常在方法中主动抛出异常,但不是什么情况下我们都应该抛出异常。原则上,自身决定不了的应该抛出。那么方法中什么时候该自己处理异常什么时候抛出?方法通常有参数,调用者在调用我们的方法帮助解决问题时,通常会传入参数,若我们方法的逻辑是因为参数的错误而引发的异常,应该抛出。
5、throws 关键字:不希望直接在某个方法中处理异常,而是希望调用者统一处理该异常。声明方法的时候,可以同时声明可能抛出的异常种类,通知调用者强制捕获。原则上 throws 声明的异常,一定要在该方法中抛出。否则没有意义。相反的,若方法中主动通过 throw 抛出一个异常,应该在 throws 中声明该种类异常,通知外界捕获。
(1)注意 throw 和 throws 关键字的区别:抛出异常和声明抛出异常。
(2)不能在 main 方法上 throws,因为调用者 JVM 会直接关闭程序。

6、捕获异常两种方式:

(1)添加 try-catch捕获该异常,

(2)在方法中声明出也追加这种异常的抛出(继续往外抛)。

7、 java 中抛出异常过程: java 虚拟机在运行程序时,一旦在某行代码运行时出现了错误,JVM 会创建这个错误的实例,并抛出。这时 JVM 会检查出错代码所在的方法是否有 try 捕获,若有,则检查 catch 块是否有可以处理该异常的能力(看能否把异常实例作为参数传进去,看有没有匹配的异常类型)。若没有,则将该异常抛给该方法的调用者(向上抛)。以此类推,直到抛至 main 方法外仍没有解决(即抛给了 JVM 处理)。那么 JVM 会终止该程序。
8、java 中的异常 Exception 分为:
(1)非检测异常( RuntimeException 子类):编译时不检查异常。若方法中抛出该类异常或其子类,那么声明方法时可以不在 throws 中列举该类抛出的异常。常见的运行时异常有:

NullPointerException

IllegalArgumentException

BufferOverflowException

ClassCastException

ConcurrentModificationException

NumberFormatException

ArrayIndexOutOfBoundsException

ArithmeticException

(2)可检测异常(非 RuntimeException 子类):编译时检查,除了运行时异常之外的异常,都是可检查异常,则必须在声明方法时用 throws 声明出可能抛出的异常种类

9、finally 块: finally 块定义在 catch 块的最后(所有 catch 最后),且只能出现一次( 0- 1 次), 无论程序是否出错都会执行无条件执行!通常在 finally 语句中进行资源的消除工作,如关闭打开的文件,删除临时文件等。

例:事务提交中的异常处理

try {
  //设置事务的提交方式为非自动提交:
  connection.setAutoCommit(false);
  
  //创建执行语句
  String sql  = "insert into dec_project_change (pro_name,manager,company) values (#{pro_name},#{manager},#{company}},'项目终止')";
  //分别执行事务
  ps = connection.prepareStatement(sql);
  ps.executeUpdate();
  //在try块内添加事务的提交操作,表示操作无异常,提交事务。
  connection.commit();
  connection.setAutoCommit(true);
} catch (Exception ex) {
  try{
	  connection.rollback(); 
  }catch(Exception e){
	  e.printStackTrace();
  }
  ex.printStackTrace();
}finally{
  try{
	  ps.close();
	  connection.close();
  }catch(Exception e){
	  e.printStackTrace();
  }        	  
}
10、重写方法时的异常处理

如果使用继承时,在父类的某个地方 throws了某些异常,而在子类别中重新定义该方法时,可以: 

(1)不处理异常(重新定义时不设定 throws)。

(2)可仅 throws 父类别中被重新定义的方法上的某些异常(抛出一个或几个)。

(3)可 throws 被重新定义的方法上的异常的子类别(抛出异常的子类)。

不可以:

(1)throws 出额外的异常。 

(2)throws 被重新定义的方法上的异常的父类别(抛出了异常的父类)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值