java异常处理
程序运行难免会出现各种各样的突发状况,即异常。
而在java程序中,正所谓万物皆对象嘛,异常在java中也是以对象的形式存在的
在最前面先放个常见的java异常体系uml图
异常的分类
在java中,按照错误的严重性可以将异常分为两大类:Error和Exception
- Error:程序在执行过程中所遇到的硬件或操作系统的错误。错误对程序而言是致命的,将导致程序无法运行。常见的错误有内存溢出,jvm虚拟机自身的非正常运行,class文件没有主方法。程序本生是不能处理错误的,只能依靠外界干预。Error是系统内部的错误,由jvm抛出,交给系统来处理。
- Exception: 是程序正常运行中,可以预料的意外情况。比如数据库连接中断,空指针,数组下标越界。异常出现可以导致程序非正常终止,也可以预先检测,被捕获处理掉,使程序继续运行。
而在Exception中,又分为编译时异常和运行时异常:
编译时异常:在编写程序时集成开发环境就会提醒你编写的程序哪里会出现异常,你不对其进行处理的话就不能通过编译
运行时异常:在编译期间不知道的,只有当程序运行起来才会抛出的异常,常见的有五大运行时异常,可以看上面的uml图
- NumerFormatException:比如字符串转数字时会抛出(“abd”->int)
- ClassCastException:类型转换异常,非法转换抛出
- IndexOutOfBoundsException:下面越界了
- ArithmeticException:算数异常,除数为0了
- NullPointerException:空指针异常,对象为null时调用对象方法时抛出
一般运行时异常不要求程序员处理,因为哪里都可能出现这种异常,如果都处理,代码就显得很长很乱
异常的处理
对于异常,有捕获和抛出两种处理方式
捕获
在java中捕获异常和处理异常所用到的语句是 try-catch(-finally) 语句
int a = 1;
int b = 0;
int c = 0
try {
c = a / b;//这里会抛出ArithmeticException
return c;
//因为上面语句抛出了异常,所以以下的语句就不会执行了,直接跳到对应的catch块执行
}catch(ArithmeticException e){//捕获顺序先小后大原则
/*处理语句*/
}catch(Exception e){
//捕获异常,可以分支捕获多种异常,也可以用他们的父类统一捕获
//e.printStackTrace();//打印异常信息
c = 0;
}finally{
//finally通常是对最后资源的收尾工作,可以没有,但是有的话不管有没有异常就一定会执行,且是最后执行,return的值以finally的为准
return c;
}
抛出
关键字:throw和throws
- throw关键字是用在一条语句上的,用于程序员手动的控制创建一个异常,可以配合程序员自定义异常使用
try{
if(a == o)
throw new MyExecption();//这个异常就是我们手动抛出的,也可以抛出java已经定义的异常
}catch(Exception e){}
- throws关键字一般是写在方法的参数列表后面的,用于表示该方法不处理这个异常,抛出去给调用这个方法的上一级,上一级也可以同样不处理抛出给更上一级,如果都不处理抛到最后就是到jvm处理了
public void m()throws IOException,ClassCastExcetion{...}
自定义异常
- 创建一个类,一般命名类…Exception,还要继承一个异常,可以是Exception(编译异常)或RuntimeException(运行时异常)
- 一般建议继承RuntimeException,因为运行时异常程序有默认的处理机制,就是会默认的throwsz这个异常,到最后给jvm处理
- 如果不是继承RuntimeException的话,throw出自定义异常还需要手动处理(try-catch或者throws),不然过不了编译
class MyException extends RuntimeException {
//继承RuntimeException如果不写try-catch会默认throws,这样就比较方便点
public MyException() {
}
public MyException(String message) {
super(message);
}
}
public class Test {
public static int test1(int a, int b) /*默认有一个throws MyException*/ {
//如果不是RuntimeException的话就要显示throws
if (a == 0){
throw new MyException();
}
int c;
c = b / a;
return c;
}
public static void main(String[] args)/*throws...*/ {
test1(0, 1);//不是继承RuntimeException这样写编译不给过
}
}