异常

异常是提高代码健壮性必不可少的部分,一个良好的程序不应缺少异常。

1.try和catch关键字

这对关键字是没什么好说的,来一段示例代码就好了吧:

package trycatch;

public class Try {
public static void main(String []args)
{
    try
    {
        int a[]=new int[10];
        for(int j=0;j<a.length;j++)
        {
            a[j]=j;
        }
        for(int l:a)
        {
            System.out.print(a[l]);
        }
        int i=a[20]/0;  //越界异常后,除0异常就不会再报了,直接执行catch部分结束,且剩下的try块中也不再执行(不管是否捕捉到)
        
    }
    catch (Exception e)
    {
        System.out.println(e.toString());
        System.out.println(e.getMessage());
    }
}
}

输出结果:0123456789java.lang.ArrayIndexOutOfBoundsException: 20

20

为什么要有这个,因为这能够保证你的程序不会崩溃,因为捕捉到异常后,程序能接着运行,但是要是异常没被捕捉,程序就不会接着运行。例如:

package trycatch;

public class Try {
public static void main(String []args)
{
    try
    {
        int a[]=new int[10];
        for(int j=0;j<a.length;j++)
        {
            a[j]=j;
        }
        for(int l:a)
        {
            System.out.print(a[l]);
        }
        int i=a[20]/0;
        
    }
    catch (NullPointerException  e)
    {
        System.out.println(e.toString());
        System.out.println(e.getMessage());
    }
    catch (ArrayIndexOutOfBoundsException  e)
    {
        
    }
    System.out.println("Others");

}
}

0123456789Others   可以接着输出Others

否则:

package trycatch;

public class Try {
public static void main(String []args)
{
    try
    {
        int a[]=new int[10];
        for(int j=0;j<a.length;j++)
        {
            a[j]=j;
        }
        for(int l:a)
        {
            System.out.print(a[l]);
        }
        int i=a[20]/0;
        
    }
    catch (NullPointerException  e)
    {
        System.out.println(e.toString());
        System.out.println(e.getMessage());
    }
    catch (StringIndexOutOfBoundsException  e)   //ArrayIndexOutOfBoundsException改为StringIndexOutOfBoundsException
    {
        
    }
    System.out.println("Others");

}
}

无法捕捉。不能继续运行,没有Others,结果如下:

0123456789Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20
at trycatch.Try.main(Try.java:17)

2.finally关键字

基本使用格式为:

try{}

catch(Exception e){}

catch(Exception e){}

finally{}

其中以上三个关键字都不能单独出现,try出现就算做一组异常,必须配合catch 或者finally或两者都出现 ,try不出现那么catch和finally也不能出现。catch可以出现多次,但不能捕捉相同的异常,包含的也不行,例如Exception和ArithmeticException。finally只能出现一次。

finally块的作用主要是回收一些数据库连接、网络连接以及文件等,因为finally总是会执行,即使异常没有被捕捉(块里出现异常和System.exit()以及其他极端情况出现除外),并且当finally执行完之后才会去执行try及catch块中的throw和return语句,而当finally块有throw或者return语句时程序直接结束,不再执行try及catch块中的throw和return语句。例如:

package trycatch;

public class Finally {
public static void main(String []args)
{
    System.out.println(Fin(2));
    System.out.println(Fin(0));
    
}
static int Fin(int a)
{
    try
    {
        int result=4/a;
        return result;
    }
    catch(Exception e)
    {
        e.printStackTrace();
        return 0;
    }
}
}

输出

2
java.lang.ArithmeticException: / by zero
0
at trycatch.Finally.Fin(Finally.java:14)
at trycatch.Finally.main(Finally.java:7)

在最后加上:

    finally
    {
        return -1;
    }

-1
java.lang.ArithmeticException: / by zero
-1
at trycatch.Finally.Fin(Finally.java:14)
at trycatch.Finally.main(Finally.java:7)

改为:

    finally
    {
        if(a==0)
        return -1;
    }

2
java.lang.ArithmeticException: / by zero
-1
at trycatch.Finally.Fin(Finally.java:14)
at trycatch.Finally.main(Finally.java:7)

3.throw和throws关键字

这两个关键字是蛮像的。throws是用于修饰方法,指代这个方法可能会出现的异常,而throw是真正抛出一个异常。

package trycatch;

public class MyException extends Exception{
public MyException(String msg)
{super(msg);}
public static void main(String []args)
{
    try {
    test(5);
    }
    catch (MyException e)
    {
        System.out.println(e.getMessage());
    }
    try {
    test(6);
    }
    catch(MyException e)
    {
        System.out.println(e.getMessage());
    }
    try {
    test(-1);
    }
    catch(MyException e)
    {
        System.out.println(e.getMessage());
    }

}
static void test(int a) throws MyException
{
    if(a>5)
    {
    System.out.println("I'm Test1");
    throw new MyException("too big");
    }
    else if(a<0)
    {
        System.out.println("I'm Test2");
        throw new MyException("too small");

    }
    System.out.println("I'm "+a); //正常代码A
}
}

I'm 5
I'm Test1
too big
I'm Test2
too small

异常抛出后,正常代码A不再执行。

3.异常的架构

 

Throwable有两个子类,Error和Exception。而异常有分为运行时异常(unchecked Exception)和非运行时异常(checked Exception),非运行时异常是能够被编译器检查到的异常,必须使用try-catch捕捉或使用throws抛出,否则编译不通过。在还没运行时,就已经报错,例如上面MyException中的例子,去除掉try-catch块,Eclipse就会提示错误,无法运行:

而重新加上抛出后可以运行,不提示错误:

 运行结果与try-catch块相同(好像运行时错误throws没用):

I'm 5
I'm Test1
too big
I'm Test2
too small

而运行时异常虽也可用上述方法处理,但是编译器无法察觉,是编程中需要极力避免的,例如除0异常、数组越界等都属于运行时异常。

常见的运行时异常
异常名称 作用
NullPointerException 空指针异常
ArrayIndexOutOfBoundsException 数组下标越界异常
ArithmeticException 算术异常
ArrayStoreException 数组中包含不兼容的值异常
IllegalArgumentException 非法参数异常
SecurityException 安全性异常
NegativeArraysizeException 数组长度为负异常
原文地址:https://www.cnblogs.com/lbrs/p/10019149.html