Java的异常处理机制

目录

 

1.异常

2.异常处理

3.Java的异常体系结构

4.处理异常的两种方式

4.1 try...catch...finally捕获异常

JDK1.7中捕获多个异常的新方案

4.2 throws抛出异常

5.throw和throws的区别 

6.finally关键字

final、finally、finalize辨析

catch中的return语句与finally语句执行顺序

7.编译期和运行期异常处理小结

8.自定义异常

9.父类和子类抛出异常说明


1.异常

Java程序运行过程中出现不正常的情况,导致程序运行中断。

2.异常处理

在程序中设置好异常的处理方式,一旦遇到异常,根据异常类型对异常进行相应的处理,处理完毕后程序继续运行。

  1. 如果我们没有对程序进行异常处理,JVM会对异常进行默认处理,将异常的信息、原因等输出并结束程序。
  2. 异常处理机制为程序提供了错误处理的能力。

3.Java的异常体系结构

Java对程序中的各种错误信息封装。

  1. Throwable:异常类的根类,它有两个子类:Error和Exception
  2. Error:程序无法处理的错误,大多是程序员无法解决的错误,比如内存溢出等。
  3. Exception:又分为运行期异常(RuntimeException及其子类)编译期异常(其他Exception)
    1. 运行期异常:通常是代码不严谨造成的,可以处理也可以不处理
    2. 编译期异常:必须对异常进行处理,否则编译不通过

4.处理异常的两种方式

4.1 try...catch...finally捕获异常

try{

    可能出现异常的代码;

}catch(异常类型 异常变量名){

    针对异常的处理;

}finally{

    无论有无异常都要执行的代码(比如释放资源);

}
  1. try:可能出现异常的代码,这部分代码不能太多,否则太消耗资源
  2. catch:
    1. 声明的异常类型尽量明确,无法明确的用Exception捕获(效率会降低)
    2. 必须要有处理代码,否则只是隐藏了异常并没有对异常进行处理
    3. 可以由多个catch,此时必须父异常在后,否则子类异常无意义
    4. 一旦try中出现异常,JVM就会抛出一个异常对象与catch中的异常类型进行匹配,匹配上就执行该catch中的处理代码,然后结束try...catch语句(后面的catch都不匹配了),继续执行后面的代码。
  3. finally:finally中的语句一定会执行。

JDK1.7中捕获多个异常的新方案

try{

    可能出现异常的代码;

}catch(异常类型1 | 异常类型2 | ... 异常变量名){

    针对上述异常的处理;

}

局限:

  1. 多个异常只能是平级关系;
  2. 对这多个异常的处理是同一种方式(实际开发中可行)

4.2 throws抛出异常

针对不想处理或没有能力处理异常的情况,Java提供了异常抛出的解决方案。

在方法上通过关键字throws声明(参数列表后)可能出现的异常类型(多个异常类型之间用逗号隔开),并没有真正的处理异常,可以理解为通知了方法调用者此处可能出现这个异常,并将异常抛给调用者进行处理。

注意:

  1. 尽量不要将异常抛给main方法,此时由JVM默认处理异常方式处理:输出异常相关信息并中断程序,异常之后的代码不会执行
//运行期的异常抛出处理
public static void method2() throws ArithmeticException {
		int a = 10;
		int b = 0;
		System.out.println(a / b);
	}

//编译期的异常抛出处理
public static void method() throws ParseException {
		String s = "2014-11-20";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date d = sdf.parse(s);
		System.out.println(d);
	}

5.throw和throws的区别 

throw:

  1. 用于方法体内,后面跟的是一个异常对象
  2. 一条throw语句只能抛出一个异常对象
  3. 表示抛出异常,由方法体内的语句来处理异常
  4. 执行throw语句一定发生了这种异常
  5. throw的对象为运行期异常时,不需要在方法声明上throws异常类;对象为编译期异常时,要在方法上throws出异常类

throws:

  1. 用于方法声明上,后面跟的是异常类
  2. 可以跟多个异常类,用逗号隔开
  3. 表示抛出异常,抛出的异常交给调用者处理
  4. 只是表示了发生异常的可能性,不一定真的发生这些异常

6.finally关键字

被finally控制的语句体一定会执行,除非在finally之前JVM退出了(比如System.exit(0))

作用:用于释放资源,比如IO流中、数据库操作中

final、finally、finalize辨析

final:

  1. 是修饰符,可以修饰类、方法、变量
    1. 修饰类,类不能被继承
    2. 修饰方法,方法不能被重写
    3. 修饰变量,对于基本数据类型的变量,值不变;对于引用类型的变量,存储的是地址值,即地址值不可变,但是指向的对象内容是可以改变的

finally:

  1. 是try...catch...finally异常处理的一部分,可以用于释放资源
    1. 一般被finally控制的语句都会执行
    2. 如果在finally之前,JVM就退出了,则不会执行

finalize:

  1. 是Object类中的一个方法,用于垃圾回收

catch中的return语句与finally语句执行顺序

  1. try...catch中由return语句时,finally中的语句仍然会执行;
  2. 先计算返回值保存起来,然后执行finally语句,最后回到之前的返回路径返回事先保存的值
  3. 如果finally中也有return语句,程序执行到finally时就会提前退出,无法再回到之前的返回路径了

7.编译期和运行期异常处理小结

  1. 对于编译时期异常,必须处理,否则编译不通过
    1. 异常代码上try...catch处理时,异常前后的代码正常执行
    2. 方法上抛出后由调用者(非JVM)处理,此时异常前后代码都执行
    3. 将异常抛给main,此时JVM默认处理,异常前代码执行,处理异常然后中断程序
  2. 对于运行时期异常,可以处理也可以不处理:
    1. 不处理,此时异常前的代码正确执行,异常代码由JVM默认处理,然后中断程序,异常后的代码不执行;
      1. 在方法声明上抛出给调用者,但调用者不处理或抛给虚拟机处理(抛出异常≠处理异常、虚拟机处理异常后中断程序)
      2. 不抛出也不处理
    2. 处理,则异常前后代码都会执行
      1. 抛出给调用者,调用者对异常进行处理
      2. 不抛出,直接try...catch处理

8.自定义异常

自定义异常类需要与异常体系形成联系——通过继承Exception类或RuntimeException类

  1. 继承自RuntimeException时,自定义的异常为运行时期异常
  2. 继承自Exception类时,自定义异常为编译期异常
  3. 自定义异常类无需编写任何成员,构造方法可写可不写
  4. 调用异常方法时仍然需要对异常进行处理
//自定义异常继承自Exception,属于编译时期异常,故要在方法上抛出
public void check(int score) throws MyException {
		if (score > 100 || score < 0) {
			throw new MyException("分数必须在0-100之间");
		} else {
			System.out.println("分数没有问题");
		}

9.父类和子类抛出异常说明

  1. 如果父类某方法抛出异常,子类在重写该方法时必须抛出与父类一样的异常或该异常的子类;
  2. 如果父类抛出多个异常,子类重写该方法时只能抛出相同异常或异常的子类,不能父类没有的异常;
  3. 如果父类某方法没有抛出异常,则子类重写该方法时不能抛出异常,若子类方法体内有一场,只能用try...catch处理不能throws抛出
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值