什么是异常?
导致程序的正常流程被中断的事件称为异常
如何处理异常?
异常的处理手段有try/catch、final、thorws
1、try/catch的使用方式
- 将可能发生异常的代码放在try中,当异常发生的时候try中的代码将被中断,转而执行catch中的代码。
- 异常的捕获通常需要调用异常父类Exception中的方法,比如发生异常的时候调用e.printStackTrace()将相关方法的调用痕迹打印出来。
- 有时候一段代码可能会有多种异常抛出,这时候可以使用多个catch进行捕获。
try{ System.out.println("试图打开 d:/LOL.exe"); new FileInputStream(f); System.out.println("成功打开"); }catch(Exception e){ System.out.println("d:/LOL.exe不存在"); e.printStackTrace(); }
2、final
finally作为异常处理的一部分,他只能出现在try/catch语句中,并附带一个语句块表示无论异常是否抛出都会被执行。通常用于需要释放资源的情况下。System.exit(0)可以阻断finally的执行
3、throws
考虑如下情况:
- 主方法调用method1
- method1调用method2
-
method2中打开文件
method2中需要进行异常处理
但是method2不打算处理,而是把这个异常通过throws抛出去
那么method1就会接到该异常。 处理办法也是两种,要么是try catch处理掉,要么也是抛出去。
method1选择本地try catch住 一旦try catch住了,就相当于把这个异常消化掉了,主方法在调用method1的时候,就不需要进行异常处理了
理解:thorws方法将异常延迟处理
4、thorw和throws的区别
throws与throw这两个关键字接近,不过意义不一样,有如下区别:
1. throws 出现在方法声明上,而throw通常都出现在方法体内。
2. throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某个异常对象。
异常的分类
异常可分为可查异常、运行时异常和错误,其中运行时异常和错误又称为非可查异常。
1、可查异常
是必须进行处理的异常。要么使用try、catch捕获,要么抛出,谁调用,谁处理。如果不处理,编译无法通过。
2、运行时异常
指的是不是必须进行捕获或抛出的异常。常见的运行时异常:
- 除数不为零的异常
- 下标越界异常
- 空指针异常
在编写代码的时候i,依然可以使用try、catch、throws进行处理,与可查异常的不同之处在于,即便不进行捕获或者抛出也不会有编译错误。Java之所以设置运行时异常的原因之一,是因为下标越界、空指针异常这些运行时异常如果都需要进行捕获代码可读性就会变得很糟糕。
3、错误
是系统界别的异常,通常是内存用完了。在默认设置下,一般Java程序在启动的时候,最大可以使用16M的内存。例如不断使用StringBuilder追加字符,把内存用完了,就会抛出OutOfMemoryError内存溢出错误。与运行时异常一样,错误也是不要求强制捕获的。
4、运行时异常和错误可以被捕获吗?
答:只要是 Throwable 的子类实例都可以捕获,所以运行时异常和错误可以被捕获。但运行时异常和错误都是不必捕获或抛出的异常,不推荐捕获因为运行时异常和错误一般都是需要修改的bug。
Throwable
1、Throwable是类,Exception和Error都继承了该类。所以在捕捉的时候,也可以使用Throwable进行捕捉
注意:但凡是Throwable的子类都可以被捕获。
2、使用Throwable进行catch
File f = new File("d:/LOL.exe");
try {
new FileInputStream(f);
//使用Throwable进行异常捕捉
} catch (Throwable t) {
// TODO Auto-generated catch block
t.printStackTrace();
}
3、问:在方法声明上,可以抛出指定的异常,比如FileNotFoundException那么能否抛出Throwable这个类?
答:可以抛出Throwable,并且在调用的时候必须进行catch处理。但是这样的设计方法做不好,因为不知道抛出的类型到底是哪种具体问题,无法针对性的处理。
自定义异常
创建一个异常类,继承自Exception类
package ExceptionTest; public class EnemyHeroIsDeadException extends Exception { public EnemyHeroIsDeadException() { } public EnemyHeroIsDeadException(String msg) { super(msg); } }
创建人物类
package ExceptionTest; public class Hero { private String name; private int hp; private int aggressivity; /** * * @param name 英雄名称 * @param hp 血量 * @param aggressivity 攻击力 */ public Hero(String name, int hp, int aggressivity) { this.name = name; this.hp = hp; this.aggressivity = aggressivity; } public void attackEnemy(Hero enemy) throws EnemyHeroIsDeadException { if (enemy.hp <= 0) { throw new EnemyHeroIsDeadException(enemy.name + " 已经挂了,不需要施放技能"); } else { enemy.hp -= this.aggressivity; } } }
测试
package ExceptionTest; public class Main { public static void main(String[] args) { Hero galen = new Hero("德玛西亚", 200, 170); Hero timo = new Hero("提莫", 150, 150); try { galen.attackEnemy(timo); galen.attackEnemy(timo); } catch (EnemyHeroIsDeadException e) { System.out.println("异常的具体原因:" + e.getMessage()); e.printStackTrace(); } } }
运行结果