Java的异常机制
什么是Java异常?
Java中,根据错误性质将错误分为了两类:错误和异常。在java中,有一个类叫Throwable,是Java中所以错误和异常的父类,它有两个子类:一个是错误类 Error 一个是异常类 Exception
- 错误::类似虚拟机断电,电脑断电等在程序中无法解决的问题,或者直接的语法或者代码错误
- 异常:程序中执行结果与预期结果不一致
异常有两种:编译器异常(Exception)和运行期异常(RuntimeException)
编译器异常:在程序编写时出现的异常,编译器会对编译期异常做出提示
运行期异常:在程序编译完成,生产.class文件,运行时产生的异常 预期结果与执行结果不一致
对于编译时的异常,运行时必须修改代码,使得编译器能够正确解释代码,但是对于运行时的异常,我们无法看到,编译器也无法看到,只有在class文件运行时才会抛出,如果我们没有处理这类异常,这个异常就会抛给虚拟机去处理:这,第一可能会终止程序运行;第二软件的健壮性不能保证。所以我们需要对异常进行处理。在处理异常之前,我们先来看看Java中常见的异常。
算术异常类:ArithmeticExecption
空指针异常类:NullPointerException
类型强制转换异常:ClassCastException
数组负下标异常:NegativeArrayException
数组下标越界异常:ArrayIndexOutOfBoundsException
违背安全原则异常:SecturityException
文件已结束异常:EOFException
文件未找到异常:FileNotFoundException
字符串转换为数字异常:NumberFormatException
操作数据库异常:SQLException
输入输出异常:IOException
方法未找到异常:NoSuchMethodException
Java的异常处理机制
java运行时的异常出现可能性非常大,所以我们需要对异常进行处理,Java处理异常的机制为try,catch,finally处理机制
格式如下
try{
//可能出现异常的代码
}
catch(异常类型){//异常声明的格式:异常的数据类型:异常的变量名称
}
catch(异常类型){//异常声明的格式:异常的数据类型:异常的变量名称
}
...
finally{
//不管是否出现异常都会执行的语句
}
这里try里面放可能出现异常的代码,catch去捕捉对应的异常,如果捕捉到对应的异常,怎执行对应的代码,finally是最终都会执行的代码,下面我写一个例子
package test;
public class Hello {
public static void hhh() {
try {
int a=1/0;
String b=null;
char c =b.charAt(0);
System.out.println("出现异常还会执行吗");
}
catch(NullPointerException e) {
System.out.println("空指针异常");
}
catch(ArithmeticException e ) {
System.out.println("算术运算异常");
}
catch(Exception e) {
System.out.println("未知异常");
}
finally {
System.out.println("异常处理最终都会执行");
}
}
public static void main(String[] args) {
hhh();
}
运行程序,结果如下:
算术运算异常
异常处理最终都会执行
可以看出,这种机制的特点是,如果出现了异常,try里面异常语句后面的代码不再执行,进入catch子句执行对应代码,最后执行finally里面的代码。然后顺序执行后面的代码,java的异常处理机制非常优秀,让我们可以轻松分辨不同种类的异常,然后对异常可以分类处理
这里有一点需要注意,在捕获异常时,子类异常的捕获要放在父类的前面,这是为什么了,比如你catch
了Exception,那么任何异常都是这个异常的子类,执行到这里,只要是异常,都会被捕获,你的其他子类异常就会被忽略
对于出现的异常,我们可以可以先不处理呢?其实也是可以的,我们需要对异常进行声明,
异常声明的格式如下:在方法后边加上 throw 异常名
最后再来说一下,即使异常throw抛出了,方法的上一级必须对该异常进行处理,如果我们一直抛出出异常而不处理,异常最终会被抛到虚拟机(JVM),虚拟机不会处理异常,它会将异常信息显示在控制台上。这也就是我们通常说的报错。
除了抛出或者处理java.lang包中的异常类,我们还可以自定义异常,格式如下
// 自定义异常 : 继承 (具有父类的特点 ) Exception 或 RuntimeException
class MyException extends Exception{
public MyException(String msg) {
// 必须通过调用父类的有参构造来传递异常信息。
super(msg);
}
}
有了自定义异常,给我们开发带来了极大的方便,我们可以根据自己项目的需求,自己的业务,自定义异常类,在合适的位置进行处理,可以更加方便处理开发过程中出现的各种异常。