1.异常和异常处理
1.异常概念
程序运行过程中发生的不正常事件,会中断正在运行的程序
2.异常处理一般方法
- 预先设置好处理方法
- JVM提供的异常处理机制
2.异常处理机制
1.关键词
try:可能出现的异常
catch:对捕获的异常进行处理
finlly:无论是否发生异常总能执行
throw:抛出异常
throws:声明异常
2.错误提示
System.err.print();(并不是所有程序都能输出为红色)
3.退出虚拟机:
非0时退出System.exit(1);
3.try-catch
三种情况
- 正常:执行try,跳过catch,执行后续代码
- 出现异常:执行try,进入catch,继续后续代码(产生异常对象与catch匹配,类似instanceof)
- 异常类型不匹配:执行try,产生异常,程序中断
4.异常对象处理
- System.err.print();自定义处理信息
- printStackTrace();输出异常的堆栈信息(一定要写上,否则就是吃掉了异常信息)
- getMessage();返回异常信息的描述字符串,是printStackTrace()输出信息的一部分(可根据实际情况选择是否输出)
//除数可能为0,产生算数异常
try {
System.out.print("输入被除数:");
int num = input.nextInt();//被除数
System.out.print("输入除数:");
int num2 = input.nextInt();//除数
int sum = num / num2;//商
System.out.print("商" + sum);
}catch (Exception e){//定义一个Exception类型的变量
e.printStackTrace();//输出异常的堆栈信息
System.err.println(e.getMessage());//输出异常信息中的描述字符串
}
5.try-catch-finally
- finally无论是否发生异常,或者是否捕捉到异常,都会执行 唯一不执行的情况:System.exit(1);
- 通常是做资源回收,例如:流的关闭,数据库的关闭
- try-catch-finally结构try是必须的,catch、finally是可选的,但至少选择其一
- try-catch-finally中有return语句先执行finally,再执行return
6.多重catch(引发多种类型的异常)
- 排列顺序必须是子类到父类,否则后续catch匹配不到,发生编译错误 按
- 顺序逐个匹配
- 只执行第一个匹配的catch语句
- 一般最后一个是Exception
7.throws和throw
1.throws声明异常
throws声明某个方法可能抛出的异常,多个异常用逗号隔开
2.throws声明的异常必须被处理
- 调用者处理异常(尽量自己处理)
- 调用者继续声明,main()方法声明的异常会由JVM处理
3.throw与throws
throw:
- 生成并抛出异常
- 位于方法体内部,可作为单独语句使用
- 抛出一个异常对象,且只能是一个
throws;
- 声明方法抛出了异常
- 必须跟在参数列表后面,不能单独使用
- 声明抛出类型,可以跟多个异常
public char sex(char sex)throws Exception{//使用throws声明该方法抛出了一个异常
if(sex=='男' || sex=='女'){
return sex;
}else {
throw new Exception("性别只能是男或女");//使用throw生成并抛出异常,抛出的是一个异常对象,需要使用new来创建
}
}
8.异常体系结构
9.自定义异常
继承Throw able或Exception(一般继承这个)
1.步骤
- 定义异常类:使用super继承父类
- 编写构造方法,继承父类的实现:super(message)
- 实例化自定义的异常对象
- 使用throw抛出
- 处理异常
//自定义年龄异常:只能在0-100之间
//第1步:定义一个类继承Exception
public class AgeException extends Exception{
//构造方法
public AgeException(){ }
//Message是Exception中的一个属性
public AgeException(String Message){
super(Message);//第2步:实现父类的重载构造方法和属性
}
}
//第4步:定义一个方法,在方法体内抛出一个自定义的异常对象,然后throw声明
public int age(int age)throws AgeException{
if(age>0 && age<100){
return age;
}else {
throw new AgeException("年龄只能在1-100之间");//第3步:实例化异常对象
}
}
//第5步:对抛出的异常进行处理
try {
int age = t.age(input.nextInt());
System.out.println("您的年龄为" + age);
}catch (AgeException e){
e.printStackTrace();//输出异常的堆栈信息
}
10.异常链与异常处理原则
1.异常链A方法调用了B方法时,B却抛出了异常,
两种方式:
- 抛出原有异常:A与B关联,不便于代码的修改和扩展
- 抛出新异常:JDK1.4后,创建了新异常并且保留了原有的异常信息(异常链)
2.异常处理原则
- 只能用于非正常情况对捕获的异常做处理
- 抛出异常会影响代码性能,尽量对捕获的异常进行catch处理;if效率更高,尽量用if
- 不要将过多的代码放在try中(不能精确捕获错误位置)
- 在catch中指定具体的异常类型(否则不利于针对性解决)