异常
概念:在程序运行过程中,出现的不正常情况叫做异常
分类:
第一级:所有异常继承于throwable
第二级:Error Exception
Error:仅靠程序本身无法恢复的严重错误
Exception:由java应用程序抛出和处理的非严重错误
第三级:
Exception下:checked异常,runtime异常
checked异常:程序必须处理该类异常,ide编译时报错
运行时异常:程序运行时出现,不要求程序必须做出处理
使用if-else解决异常问题:1.代码臃肿2.需要花很大精力堵漏洞3.很难堵住所有漏洞
打印异常信息
void e.printStackTrace();//打印异常堆栈信息,
//可以从异常信息的最后一行开始追踪,寻找自己编写的java类
String e.getMessage();
使用异常机制
java的异常处理通过5个关键字来实现:try、catch、finally、throw、throws
异常处理的方式:
try-catch捕获异常:
try{
//代码逻辑
}catch(Exception e){
//异常处理逻辑
}catch(Exception e){
}
注:使用多重catch时,将子类catch放在前面,父类catch放在后面
使用try-catch语句,不管有没有出现异常,try-catch语句块后面的程序都会正常执行
finally
在程序运行过程中,如果处理异常的部分包含finally的处理,那么无论代码是否发生异常,finally这种的代码总会执行
finally中一般包含哪些处理逻辑:
1.IO流的关闭操作一般设置在finally中
2.数据库的连接关闭操作设置在finally中
throws 声明异常
在异常情况出现的时候,可以使用try…catch…finally的方式对异常进行处理,除此之外,可以将异常向外抛出,由外部的进行处理
在方法调用过程中,可能存在N多个方法之间的调用,此时假如每个方法都包含了异常情况,那么就需要在每个方法中都进行try…catch,另外一种比较简单的方式,就是在方法的最外层调用处理一次即可
使用throws的方式,对所有执行过程中的所有方法出现的异常进行统一集中处理
如何判断是使用throws还是使用try…catch…?
最稳妥的方式是在每个方法中都进行异常的处理
偷懒的方式是判断在整个调用的过程中,外层的调用方法是否有对异常的处理,如果有,直接使用throws,如果没有,那么就要使用try…catch…
throw 抛出异常
public static void show() throws Exception{
String gender="123";
if(gender.equals("man")){
System.out.println("man");
}else if(gender.equals("women"){
System.out.println("woman");
}else{
//throw new Exception("性别出现错误");
throw new GenderException();//自定义异常
}
}
自定义异常
步骤:
1.继承Exception类
2.自定义实现构造方法
3.需要使用的时候,使用throw new 自定义异常的名称
public class GenderException extends Exception{
public GenderException(){
System.out.println("性别异常");
}
public GenderException(String msg){
System.out.println(msg);
}
}
try-catch-return
情形一,try中有return,finally中没有return
private static int test(){
int num = 10;
try{
System.out.println("try");
return num += 80;
}catch(Exception e){
System.out.println("error");
}finally{
if (num > 20){
System.out.println("num>20 : " + num);
}
System.out.println("finally");
}
return num;
}
}
输出结果:
try
num>20:90
finally
90
先执行finally,再return
情况二,try和finally中均有return
private static int test(){
int num = 10;
try{
System.out.println("try");
return num += 80;
}catch(Exception e){
System.out.println("error");
}finally{
if (num > 20){
System.out.println("num>20 : " + num);
}
System.out.println("finally");
num = 100;
return num;
}
}
}
输出结果:
try
num>20 : 90
finally
100
finally中的return语句先于try中的return语句执行,因而try中的return被覆盖,不再执行。
情形三,finally中改变返回值num
private static int test(){
int num = 10;
try{
System.out.println("try");
return num;
}catch(Exception e){
System.out.println("error");
}finally{
if (num > 20){
System.out.println("num>20 : " + num);
}
System.out.println("finally");
num = 100;
}
return num;
}
输出结果:
try
finally
10
try中的num的值是程序进入finally代码块前保留下来的值
情形四,将num的值包装在Num类中
private static Num test(){
Num number = new Num();
try{
System.out.println("try");
return number;
}catch(Exception e){
System.out.println("error");
}finally{
if (number.num > 20){
System.out.println("number.num>20 : " + number.num);
}
System.out.println("finally");
number.num = 100;
}
return number;
}
输出结果:
try
finally
100
改变了引用类型对象的值
finally语句块唯一不执行的情况
使用System.exit(1)语句退出Java虚拟机,不执行finally
常见的异常类型
异常类型 | 说明 |
---|---|
Exception | 异常层次结构的父类 |
ArithmeticException | 算术错误情形,如:以0作为除数 |
ArrayIndexOutOfBoundsException | 数组下标越界 |
NullPointerException | 尝试访问null对象成员 |
ClassNotFoundException | 不能加载所需的类 |
IllegalArgumentException | 方法接收到非法参数 |
ClassCastException | 对象强制类型转换出错 |
NumberFormatException | 数字格式转换异常,如:将”abc“转换成数字 |