异常处理

来源:互联网 发布:it资产管理系统 php 编辑:程序博客网 时间:2024/06/05 05:32

1异常类的继承

1.try块里声明的变量是代码块内部局部变量,它只在try块内有效,在catch块中不能访问该变量。
2.异常(Exception)和错误(Error)两种,Exception可以被捕获,而Error错误,一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,动态链接失败等,这种错误无法捕获或无法恢复,故catcha是不能捕获到Error对象,也无须在其throws子句中声明该方法可能抛出Error及其任何子类,异常的继承图:
异常类继承图
3.进行异常捕获时不仅应该把Exception类对应的catch块放在最后,而且所有的父类异常的catch块都应该排在子类异常catch块的后面(遵循先处理小异常,再处理大 异常)
4.捕获多种类型的异常时,多中异常类型之间用竖线(|)隔开,异常变量有隐式的final修饰,因此程序不能对异常变量重新赋值
代码例子:

public class MultiExceptionTest{    public static void main(String[] args)     {        try        {            int a = Integer.parseInt(args[0]);            int b = Integer.parseInt(args[1]);            int c = a / b;            System.out.println("您输入的两个数相除的结果是:" + c );        }        catch (IndexOutOfBoundsException|NumberFormatException            |ArithmeticException ie)        {            System.out.println("程序发生了数组越界、数字格式异常、算术异常之一");            // 捕捉多异常时,异常变量默认有final修饰,            // 所以下面代码有错:            ie = new ArithmeticException("test");  //①        }        catch (Exception e)        {            System.out.println("未知异常");            // 捕捉一个类型的异常时,异常变量没有final修饰            // 所以下面代码完全正确。            e = new RuntimeException("test");    //②        }    }} 

5.异常处理语法结构中只有try块是必需,而catch和finally是可选的(但必需catch和finally块至少出现其中之一),catch如果有return语句,在执行return语句之前,程序还会执行finally块,但如果catch如果有System.exit(1)语句,则不会执行finally块。
代码例子:

public class FinallyTest{    public static void main(String[] args)     {        FileInputStream fis = null;        try        {            fis = new FileInputStream("a.txt");        }        catch (IOException ioe)        {            System.out.println(ioe.getMessage());            //return语句强制方法返回,会执行下面的finally            return ;       //①            //使用exit来退出虚拟机,不会执行下面的finally            //System.exit(1);     //②        }        finally        {            //关闭磁盘文件,回收资源            if (fis != null)            {                try                {                    fis.close();                }                catch (IOException ioe)                {                    ioe.printStackTrace();                }            }            System.out.println("执行finally块里的资源回收!");        }    }}

6.不要在finally块中使用如return或throw等导致方法终止的语句,一旦在finally快中使用了return或throw语句,将会导致try块,catch块中的return,throw语句失效。
代码例子:

public class FinallyFlowTest{    public static void main(String[] args)        throws Exception    {        boolean a = test();        System.out.println(a);    }    public static boolean test()    {        try        {            // 因为finally块中包含了return语句            // 所以下面的return语句失去作用            return true;        }        finally        {            return false;        }    }}

7.java7以后,允许try关键字后紧跟一对圆括号(这里try语句相当于包含了隐式的finally,所以后面不需要有catch和finally块),圆括号里可以声明,初始化一个或多个资源,此处的资源指的是那些必须在程序结束时显示关闭的资源(比如数据库连接,网络连接),try语句在该语句结束时会自动关闭这些资源(这些资源实现类必须实现AutoCloseable或Closeable接口)
代码例子:

public class AutoCloseTest{    public static void main(String[] args)         throws IOException    {        try (            // 声明、初始化两个可关闭的资源            // try语句会自动关闭这两个资源。            BufferedReader br = new BufferedReader(                new FileReader("AutoCloseTest.java"));            PrintStream ps = new PrintStream(new                FileOutputStream("a.txt")))        {            // 使用两个资源            System.out.println(br.readLine());            ps.println("庄生晓梦迷蝴蝶");        }    }}

2Checked异常和Runtime异常体系

1.Checked异常需要程序显示处理(一般是通过try…catch),否则程序会产生编译错误,而Runtime异常则不要程序显示处理。
代码例子:

public class Test{    public static void g() throws RuntimeException    {        String a=null;    }       public static void t() throws Exception    {        String a=null;    }    public static void main(String[] args)     {        //编译通过,因为异常是UnChecked类型        g();        //编译不通过,因为异常是Checked类型        //要么用try,要么用throws,编译才能通过        t();    }}

3使用throw抛出异常

1.throw语句常用于catch代码快中,其抛出的不是异常类,而是异常实例,且只能抛出一个异常实例。
2用户自定义异常都应该继承Exception基类,如果希望自定义Runtime异常,则应该继承RuntimeException基类,一般需要提供两个构造器:一个是无参数的构造器,另一个是带一个字符串参数的构造器。
代码例子:

public class AuctionException extends Exception{    //无参数的构造器    public AuctionException(){}       //①    //带一个字符串参数的构造器    public AuctionException(String msg)    //②    {        super(msg);    }}

3.java7以后,Java编译器会执行更细致的检查,Java编译器会检查throw语句抛出异常的实际类型
代码例子:

public class ThrowTest2{    public static void main(String[] args)        // Java 6认为①号代码可能抛出Exception,        // 所以此处声明抛出Exception//      throws Exception        // Java 7会检查①号代码可能抛出异常的实际类型,        // 因此此处只需声明抛出FileNotFoundException即可。        throws FileNotFoundException    {        try        {            new FileOutputStream("a.txt");        }        catch (Exception ex)        {            ex.printStackTrace();            throw ex;        //①        }    }}

4.捕获一个异常然后接着抛出另一个异常,并把原始信息保存下来,这种典型的链式处理被称为“异常链”,JDK1.4以后,所有Throwable的子类在构造器中都可以接受一个cause对象作为参数,而这个cause就来表示原始异常。
代码例子:
第一种不使用异常链处理:

public class Test{    public static void g()    {        try        {            String a=null;            System.out.println(a.length());        }         catch (Exception e)        {                       throw new RuntimeException();        }    }       public static void main(String[] args)     {        System.out.println("g()方法异常信息");        g();            }}

运行结果:
**g()方法异常信息
Exception in thread main java.lang.RuntimeException**
第二种使用异常链处理:

public class Test{    public static void t()    {        try        {            String a=null;            System.out.println(a.length());        }         catch (Exception e)        {                       throw new RuntimeException(e);        }    }       public static void main(String[] args)     {        System.out.println("t()方法异常信息");        t();            }}

运行结果:
**Exception in thread main java.lang.RuntimeException: java.lang.NullPointerException
Caused by: java.lang.NullPointerException**
比较这两种的运行结果了,可以看出,异常链式处理打印出了最原始的异常信息,而非异常链式处理只打印最后一个抛出的异常信息。

4Java的异常跟踪栈

1. 异常的传播规则:只要异常没有被完全捕获(包括异常没有被捕获,或异常被处理后重新抛出了新异常),异常从发生异常的方法逐渐向外传播,首先传给该方法的调用者,该方法调用者再次传给其调用者…….
代码例子:

class SelfException extends RuntimeException{    SelfException(){}    SelfException(String msg)    {        super(msg);    }}public class PrintStackTraceTest{    public static void main(String[] args)    {        firstMethod();    }    public static void firstMethod()    {        secondMethod();    }    public static void secondMethod()    {        thirdMethod();    }    public static void thirdMethod()    {        throw new SelfException("自定义异常信息");    }}

运行结果:
**Exception in thread ‘main’ csdn1.SelfException: 自定义异常信息
at csdn1.PrintStackTraceTest.thirdMethod(PrintStackTraceTest.java:27)
at csdn1.PrintStackTraceTest.secondMethod(PrintStackTraceTest.java:23)
at csdn1.PrintStackTraceTest.firstMethod(PrintStackTraceTest.java:19)
at csdn1.PrintStackTraceTest.main(PrintStackTraceTest.java:15)**
这篇博客参考资料
Java疯狂讲义2

0 0