Java异常处理机制
Java已经提供了异常处理机制,发生异常后,会给出异常类型、异常提示信息、异常的位置等。但这样有一个缺点,就是出现异常后,后续代码不执行了;提示信息太专业,可读性差。所以我们使用两种解决办法来处理异常:try-catch捕获异常和throws抛出异常。
异常分类
异常处理
try-catch
情况1:try块中代码没有出现异常
不执行catch块代码,执行catch块后边的代码
情况2:try块中代码出现异常,catch中异常类型匹配(相同或者父类)
执行catch块代码,执行catch块后边的代码
情况3:try块中代码出现异常, catch中异常类型不匹配
不执行catch块代码,不执行catch块后边的代码,程序会中断运行
注意
出现异常后,Java会生成相应的异常对象,Java系统,寻找匹配的catch块,找到后将异常对象付给catch块异常参数
出现异常后,try块中尚未执行的语句不会执行
出现异常后并处理后,catch块后面的语句还会执行
catch块中如何处理异常
1.输出用户自定义异常信息
System.err.println("除数不能为零。");
System.err.println("被除数和除数必须是整数。");
2.调用异常对象的方法输出异常信息
toString ( )方法,显示异常的类名和产生异常的原因
void printStackTrace() 输出异常的堆栈信息
String getMessage()返回异常信息描述字符串,是printStackTrace()输出信息的一部分
3.继续向上抛出异常
throw e
在什么情况下,catch后面的语句是不执行的
1.catch块中有throw 子句。
2.catch中有return子句。
3.catch块中的异常与发生的异常不匹配。
finally块
如果想让某些代码必须执行,可以加上finally块。
finally在实际开发中的使用场合:IO流的管理,数据库连接的关闭 ,socket的关闭等。
如果try块中含有return子句,则先执行finally块中的代码,在执行return子句。
如果try块中含有System.exit(1)子句,则终止当前正在执行的Java虚拟机,不会再执行finally块中的代码。
/**
* 执行结果是
* 2
* 3
* 结果:3
* @return
*/
public static void main(String[] args) {
System.out.println("结果:"+TestException6.get());
}
public static int get(){
try {
Integer a=null;
a.toString();
System.out.println(1);
return 1;
} catch (Exception e) {
System.out.println(2);
return 2;
} finally {
System.out.println(3);
return 3;
}
}
多重catch
1.当引发异常时,会按顺序来查看每个 catch 语句,并执行第一个与异常类型匹配的catch语句
2.执行其中一条 catch 语句后,其后 catch 语句将被忽略
3.在安排catch语句的顺序时,首先应该捕获最特殊的异常, 然后再逐渐一般化,即先子类后父类
4.try子句必须存在,catch和finally至少有一个
5.jdk7后支持catch(Exception1 | Exception2 | Exception3)的语法格式,使代码更简洁
throws和throw
throws:声明异常当Checked Exception产生时,不一定立刻处理它,可以再把异常Throws出去让调用者处理该异常
如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号隔开
子类声明的异常范围不能超过父类声明范围
父类没有声明异常,子类也不能
不可抛出原有方法抛出异常类的父类或上层类
throw:手动抛出异常
Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要手工创建并抛出。
在捕获一个异常前,必须有一段代码先生成异常对象并把它抛出。这个过程我们可以手工做,也可以由JRE来实现,但是他们调用的都是throw子句。
注意抛出运行时异常和Checked异常的区别
抛出Checked异常,该throw语句要么处于try块中,要么方法签名中石油throws抛出
抛出运行时异常,没有以上要求
自定义异常
在程序中,可能会遇到任何标准异常类都没有充分的描述清楚的问题,这种情况下可以创建自己的异常类
从Exception类或者它的子类派生一个子类即可
习惯上,定义的类应该包含2个构造器:一个是默认构造器,另一个是带有详细信息的构造器
/**
* 自定义异常
* 1.一般继承Exception或者RuntimeException
* 2.一般只要提供无参数和Sting参数构造方法即可
* 3.某些情况下需要重写toString()
* @author Administrator
*
*/
public class DivideByMinusException extends RuntimeException{
private int num;
public DivideByMinusException() {
super();
}
public DivideByMinusException(String message) {
super(message);
}
public DivideByMinusException(String message, int num) {
super(message);
this.num = num;
}
@Override
public String toString() {
return super.toString()+":("+num+")";
}
}