Java异常及相关处理

1.Throwable的两类子类

Error类:是程序运行时候抛出的最严重级别的错误,如VirtualMachineError,ThreadDeath。抛出了Error的程序从Java设计的角度来讲,程序基本不可以通过后续代码修复,从而理应终止。从语法上来讲,所有这些都可以被写进catch里面,但是Error因为上述原因,不应该被代码处理。

Exception类:又分为可检查(checked)异常和不检查(unchecked)异常,可检查异常在源码里必须显示的进行捕获处理,这里是编译期检查的一部分。不检查异常就是所谓的运行时异常,类似NullPointerException,ArrayIndexOutOfBoundsExceptin之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译器强制要求。

2.Java Error类与Exception类的区别

Error和Exception都是Throwable的子类。一般意义来讲,区别就是Error比Exception更严重,不易通过后续代码处理和修复,不应该被代码catch到的错误。而Exception是指严重程度较轻的程序问题,相较于Error更容易被后续代码处理和修复的,有些需要通过try catch代码处理,有些不建议通过try catch代码处理。

4.异常处理的两种方式

方式一:捕获处理
捕获处理格式:

try{
	可能发生异常的代码
}catch(捕获的异常类型 变量名){
	处理异常的代码
}
...
}catch(捕获的异常类型 变量名){
	处理异常的代码
}
finally{
    无论try中是否有异常,也不管catch是否可以捕获异常,也不管try和catch中是不是有return,都会执行
}

注:

  • 如果try块中代码出现了异常经过处理之后,那么try-catch块外面的代码可以正常行。
  • 如果try块中代码出现了异常的代码,那么try块中出现异常代码后面的代码时不会执行的。
  • 一个try块后面时可以跟多个catch块的,即一个try块可以捕获多种异常的类型。
  • 一个try块可以捕获多种异常的类型,但是捕获的异常类型必须从小到大进行捕获,否则编译报错。

实例:

public class ExceptionDemo2 {
    public static void main(String[] args) {
        try {
            show(1);
        }catch (NullPointerException e) {
            System.out.println("空指针异常");
        }catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组下标越界异常");
        }finally {
            System.out.println("一定会执行");
        }
        System.out.println("程序结束!");
    }
    private static void show(int a) {
        if (a == 0) {
            int[] arr = new int[0];
            System.out.println(arr[1]);
        }else {
            int[] arr = null;
            System.out.println(arr.length);
        }
    }
}

方式二:抛出处理(throw throws)

注:

  • 如果一个方法的内部抛出了一个异常对象,那么,必须要在方法上声明抛出。
  • 如果调用了一个声明抛出异常的方法,那么调用者必须要处理异常。
  • 如果一个方法内部抛出了一个异常对象,那么throw语句后面的代码都不会在执行了。
  • 在一种情况下,只能抛出一种类型的异常对象。

实例:

public class ThrowsDemo {
    public static void main(String[] args) throws ClassNotFoundException, FileNotFoundException {
        method01(0);
    }

    private static void method01(int a) throws ClassNotFoundException, FileNotFoundException {
        if (a == 0){
            throw new ClassNotFoundException("类型不存在!");
        }else {
            throw new FileNotFoundException("文件不存在!");
        }
    }
}

5.举例RuntimeException类的五个子类

1.ClassCastException类型强制转换异常

Object x = new Integer(0);
System.out.println((String)x);

当试图将对象强制转换为不是实例的子类时,抛出该异常


2.ArithmeticException算术异常类

int a=5/0;

一个整数“除以零”时,抛出异常


3.NullPointerException空指针异常类

String s=null;
int size=s.size();

当应用程序试图在需要对象的地方使用 null 时,抛出异常

4.ArrayIndexOutOfBoundsException数组下标越界异常

int[] num = new int[5];
System.out.println(num[5]); 

当使用的数组下标超出数组允许范围时,抛出该异常

5.NegativeArraySizeException数组负下标异常

String[] ss=new String[-1];

数组大小为负值异常。当使用负数大小值创建数组时抛出该异常
如应用程序试图创建大小为负的数组,则抛出异常
 

6.异常中的throws声明与throw语句的区别

throw:

  • 表示方法内抛出某种异常对象
  • 如果异常对象是非 RuntimeException 则需要在方法申明时加上该异常的抛出 即需要加上 throws 语句或者在方法体内 try catch 处理该异常,否则编译报错
  • 执行到 throw 语句则后面的语句块不再执行


throws:

  • 方法的定义上使用 throws 表示这个方法可能抛出某种异常
  • 需要由方法的调用者进行异常处理

举例:

void doA(int a) throws Exception1,Exception3{
           try{
                 ......

           }catch(Exception1 e){
              throw e;
           }catch(Exception2 e){
              System.out.println("出错了!");
           }
           if(a!=b)
              throw new  Exception3("自定义异常");
}
/**
代码块中可能会产生3个异常,(Exception1,Exception2,Exception3)。
如果产生Exception1异常,则捕获之后再抛出,由该方法的调用者去处理。
如果产生Exception2异常,则该方法自己处理了(即System.out.println("出错了!");)。所以该方法就不会再向外抛出Exception2异常了,void doA() throws Exception1,Exception3 里面的Exception2也就不用写了。
而Exception3异常是该方法的某段逻辑出错,程序员自己做了处理,在该段逻辑错误的情况下抛出异常Exception3,则该方法的调用者也要处理此异常。
*/

7.finally子句的作用

finally子句是异常捕获的一部分

try{
}catch(Exception e){
}finally{
}

三部分的执行顺序是try块检测并抛出异常,然后由catch子句捕获,最后执行finally子句。
try块必须有,catch和finally子句不一定全都必须,可以二选一,也可都有。

finally是这个组合语句的统一出口,一般用来进行一些善后清理操作,例如清理资源、释放连接、关闭文件、管道流等操作。它是可选的部分,但一旦选定,必定执行。

public class TestFinally {
    public static void main( string[] args) {
        system.out.printLn(testFinally());
    }
    private static int testFinally() {
        int temp = 100;
        try {
            system.out. println( "Try " ); 
            return ++temp;//return的结果被暂存
        }
        finally {
            temp = 1;
            system.out.println( "Finally" );
        }
    }
}

结果为: 

Try
Finally
101

finally代码块在return语句运行后执行的。return结果被暂存,等finally代码块执行结束后再将之前暂存的结果返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值