Java-异常

目录

异常

编程时往往会遇到程序异常的情况,在Java中,通过面向对象方法处理异常,发生异常就是产生一个异常对象,所以异常和错误是不同的。


概念

  • Throwable:Java中所有异常类型都是内置类java.lang.Throwable类的子类,位于异常层次机构的顶层。

  • 错误(Error):JVM无法语预期的错误,属于JVM层次的严重错误,一般是由JVM抛出。导致JVM无法继续执行,所以这是无法捕获或修复的,即程序员不能通过代码处理的,一般这种情况就是保证程序安全退出。比如虚拟机错误、内存溢出、线程死锁等。

  • 异常(Exception):Exception及它的子类,可以被Java异常处理机制使用,可恢复可捕获,是异常处理的核心。

  • 运行时异常:javac在编译时,不会提示发现这样的异常,对于这些异常编译可以通过,但程序不会处理运行时异常,出现这类异常,程序会停止。例如:

    算数异常( java.lang.ArithmeticException: / by zero)、
    指定的类不存在(java.lang.classnotfoundexception)、
    数组索引越界(java.lang.arrayindexoutofboundsexception)、
    空指针异常(java.lang.nullpointerexception)等。

    这些异常应该通过修正代码,而不是通过异常处理器处理,因为多半是代码编写有问题。

  • 非运行时异常:javac强制要求程序员为这样的异常做预处理工作(使用try...catch,,,finally或者throws)。在方法中使用try...catch语句捕获并处理,或者用throws字句声明抛出它,否则无法编译通过。这样的异常一般与运行环境导致,因为程序可能被运行在各种未知的环境下,而程序员无法干预用户使用程序,所以应该为这样的异常时刻准备着。如SQLException、IOException、ClassNotFoundException等。

  • 另一种叫法:检查和非检查异常,这是对于javac(编译器)来说的,是否运行编译通过这样的异常。

    检查异常(checked exception)除Error和Runtime 的其他异常,javac强制要求为这样的异常做预备处理(try...catch或throws)否则编译不通过。
    非检查异常:Error和RuntimeException及其子类。不提示发现这样的异常,不在程序处理这些异常(可以处理也可以不处理)

Java-异常


异常处理

抛出异常

  • 当一个方法出现错误并引发异常时,方法就会创建异常对象并交付运行时系统。
  • 异常对象包含异常类型和异常出现时的程序状态等异常信息。
  • 运行时系统负责寻找处理异常的代码并执行。
  • 抛出异常的方法:throw和throws

捕获异常

  • 由于运行时异常(RuntimeException)的不可查性,运行时异常由,Java运行时系统自动抛出,允许应用程序忽略运行时异常。
  • 对于方法运行中可能出现的错误(Error),当运行方法不想捕获时,Java允许该方法不做任何抛出声明,因为多数Error异常属于永远不能被允许发生的情况,即合理的应用程序不该捕获的异常。
  • 对于所有的可查异常,当一个方法选择不捕获可查异常时,它必须声明或抛出异常。
  • 总之,对于可查异常必须捕获或者声明抛出,允许忽略不可查的运行时异常和错误

关键字

Java-异常

throw和throws

throw

throw用于明确抛出一个异常对象,语句抛出一个异常。声明在方法体内

 throw e;   //throw (异常对象);

抛出一个异常类的实例化对象。try语句要捕获一个异常对象,那么这个异常对象可以是自己抛出的。

public class Test4 {
    public static void main(String[] args) {
        try {
            throw new Exception("这是自己throw抛出一个异常对象");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e);
        }
    }
}

Java-异常


throws

throws属于异常处理的一种方式,声明在方法的声明处,表示此方法不处理异常,交给方法调用者处理。

public void test(int i) throws Exception1,Exception2 { //... }

throws Exception , Exception 2 只是告诉程序这个方法可能会抛出这些异常,方法的调用者可能要处理这些异常,而Excepton1,Exception2这些异常可能是由该函数体产生的。

public class Test3{
    public static void test(int i) throws Exception {
        int a = 5/i ;
        System.out.println(a);
    }
    public static void main(String[] args) throws Exception {
        test(0);
        /**
         输出结果: 算数异常
         Exception in thread "main" java.lang.ArithmeticException: / by zero
         */
    }
}

在本程序中,主方法(main)不处理任何异常,而是交给JVM,所以在主方法使用throws表示交给JVM处理。在主方法中,所有异常都可以不使用try...catch处理异常。


区别一下

  • throws用在方法声明后,表示再抛出异常,throws将异常抛给上一级,由方法调用者处理。
  • throw在方法体中,抛出异常,并且throw后语句不执行,必须使用try...catch(finally可以用,也可以不用)。
  • throws表示出现异常的可能性,throw则是抛出异常,一定抛出某种异常。

e.printStackTrace();

API:将此 throwable 及其追踪输出至标准错误流。即:

在命令行打印异常信息在程序中出错的位置及原因。
Java-异常


finally

关于finally在另一篇文章里 finally相关问题(finally块中的代码,真的是一定执行吗?)


需要注意的地方

  • try块、catch块、finally块中的局部变量、异常变量他们之间不可共享使用。
    Java-异常

  • 每一个catch块用于处理一个异常,按照顺序从上到下匹配异常,只有第一个匹配的catch会执行,所以父类异常要放在后面。
public class Test3{
    public static void test(int i){
        int a = 5/i ; //异常抛出点
        System.out.println("test"); //未执行
    }
    
    public static void main(String[] args) {
        try{
            test(0);
        }
        catch (NullPointerException e1){
            System.out.println("空指针异常");
        }
        catch (ArithmeticException e2){
            System.out.println("算数异常");
        }finally {
            System.out.println("finally");
        }

        /**
         * 输出结果:
         * 算数异常
         * finally
         */
    }
}
  • test方法中遇到异常抛出点,就执行异常处理,后面的语句不会执行。

  • 异常处理的任务就是将执行控制流,从异常发生的地方转移到能够处理这种异常的地方去。所以当某条语句发生异常后,这条语句后面将不会执行,失去了焦点。执行流跳转到匹配的异常处理catch代码块去执行。

  • Java在处理后,让执行流恢复到处理了异常的catch块后接着执行,这种策略叫做终结式异常处理模式


我的csdn:https://blog.csdn.net/weixin_45910779/article/details/113778266

上一篇:java-throw和throws


下一篇:PHP 异常处理