Java中的异常体系:
Throwable类是Java 语言中所有错误或异常的超类。Throwable分为两大类,Error和Exception(异常)
Error作为程序员基本不会碰到,因此我们就直接pass。
接下来主要讲Exception,Exception也分为两大类,一类是RuntimException,l另一类不是RuntimeException,RuntimException是指运行时异常,这种异常类及其所有子类,是一种可以选择性捕获(可以捕获,也可以不捕获)的异常。这种异常使我们平时见得比较多的异常。例如:NullPointerException、ClassCastException、ClassCastException等等。当这种异常发生的时候,程序就直接终止,发生异常的代码片段之后的代码都不会得到执行。在发生这种异常的时候,不捕获的话编译器也不会报错,只有等到发生该异常的时候才会被发现。因此要熟记这些运行时异常发生的条件以及如何处理这种异常。
发生异常的时候有两种方法处理该异常:
第一种:使用try...catch块来处理该异常,try语句块包含所有可能发生异常的代码块,catch语句捕获发生的异常类型,并使用e.printStackTrace()来输出发生异常时具体的出错信息,以便用来排错。catch语句块用来表示当发生该异常时要执行的操作。在执行任何操作的额时候都要讲出错信息发送到控制台上并加上自己自定义的出错后执行的具体操作。
第二种:当发生异常的时候使用throws关键字在方法的后面抛出该异常,由这个方法的调用者来处理该异常,方法的调用者可以使用try...catch来处理该异常,也可以继续上抛,知道抛到超类Throwable上面,交给它来处理,它的处理方式就是讲出错信息输出到控制台上,然后程序结束。实际上就等于没有对异常做任何处理。因此推荐大家在发生异常的本地就处理掉该异常。
一个try语句后面可以跟多个catch块。用来捕获更多的异常,当有多个异常发生需要捕获的时候,本着异常从小到大的原则使用catch块排列。有着兄弟关系的异常排名不分先后。运行时异常要排在非运行时异常的前面 。
在发生异常的代码片段之间使用try块包含住所有可能发生该异常的代码块(在Eclipse中的快捷键是 shift + Alt + z),这样发生该异常的时候就可以处理掉该异常。并且异常捕获之后,发生异常之后的程序片段依然可以被执行。
有时我们需要无论异常是否发生都需要执行一些代码片段,这时就可以在try...catch语句块后面加上一个finally关键字用来表示无论异常是否发生都需要执行的代码块。这与try...catch语句之外的代码块不一样,语句之外的代码块是只有等到异常发生的时候才会被执行。当没有异常出现的时候也就不会发生。但是这种的话无论异常是否发生都要执行。
example;
try{
}catch(Exception e){
e.printStackTrace();
//异常发生后要进行的操作,用户可以自定义要执行什么操作
}finally{
//无论异常是否发生都会执行的代码片段
}
//当捕获到异常时才会执行的代码块
System.out.println("当捕获到异常时才会执行的代码块");
除此之外的异常都是非运行时异常,是需要强制捕获的,否则编译时报错。常见的运行时异常有ClassnotFoundException、SQLException等等。当执行一些方法有可能发生这种异常的时候,编译器会自动提示可能发生这种强制捕获异常。要求必须处理该异常。
在发生异常的时候一般后面都会给具体的异常信息,这个一场信息用户也可以自定义,比如说当输入一个人的年龄小于等于0的时候就发生该异常,在年龄age这个的setter方法中可以这么定义:
if(age <= 0){
throw new IllegalArgumentException("年龄不能小于等于零");
}else{
this.age = age;
}
除此之外,用户也可以自定义异常类,在自定义异常类的时候首先要确定这种异常类是非强制捕获的还是强制捕获的。当是强制捕获的时候就要在声明这个异常类的时候继承Exception这个类。当时非强制捕获的时候就要继承RuntimeException这个类。
声明自定义的异常类之后可以写异常类的构造方法,并且可以重写构造方法,一边在异常发生的时候传入不同的参数。
依然以输入年龄不能小于等于0为例。自定义一个非运行时异常(强制捕获该异常)
example:
public class MyAgeException extends Exception {
private static final long serialVersionUID = 1L;
public MyAgeException(){}
public MyAgeException(String message){
super(message);
}
}
举例:在自定义的User实体类中的age的setter方法中判断输入的年龄是否小于等于0,如果小于等于零的抛出一个自定义异常类的对象(带参数),这个时候就会将异常抛给方法的调用者,方法的调用者使用try...catch来捕获该异常,当异常发生的时候会返回在setter中传入字符串参数的自定义出错信息。
example:
public void setAge(int age) throws MyAgeException {
if(age <= 0){
throw new MyAgeException("年龄不能小于等于0");
}
}
方法的调用者使用try...catch处理该异常
try {
User user = new User();
user.setAge(-19);
} catch (MyAgeException e) {
e.printStackTrace();
}
发生异常的时候控制台输出异常具体出错信息:年龄不能小于等于0