什么是异常?
异常是一个不需要的或意外的事件,它发生在程序执行过程中,即在运行时发生,这会中断程序指令的正常流程。
错误与异常
错误: 错误表示合理应用程序不应尝试捕捉的严重问题。
异常: 异常表示合理应用程序可能尝试捕获的条件。
异常层次结构
所有异常和错误类型都是Throwable类的子类,它是层次结构的基类。一个分支由Exception引导。这个类用于用户程序应该捕获的特殊条件。NullPointerException是此类异常的一个示例。Java运行时系统(JVM)使用另一个分支Error指示与运行时环境本身(JRE)有关的错误。StackOverflowError是这种错误的一个例子。
默认异常处理:只要在方法内部,如果发生异常,该方法就会创建一个名为异常对象的对象,并将其交给运行时系统(JVM)。异常对象包含异常的名称和描述,以及发生异常的程序的当前状态。创建异常对象并将其处理到运行时系统称为抛出一个异常。可能有一些已调用的方法列表,用于发生异常的方法。这个有序的方法列表被称为调用堆栈。现在将执行以下过程。
Exception in thread "xxx" Name of Exception : Description ... ...... .. // Call Stack
请参阅下图以了解调用堆栈的流程。
示例:
// Java program to demonstrate how exception is thrown. class ThrowsExecp{ public static void main(String args[]){ String str = null; System.out.println(str.length()); } }
输出:
Exception in thread "main" java.lang.NullPointerException at ThrowsExecp.main(File.java:8)
让我们看一个例子,说明运行时系统如何在调用栈上搜索适当的异常处理代码:
// Java program to demonstrate exception is thrown // how the runTime system searches th call stack // to find appropriate exception handler. class ExceptionThrown { // It throws the Exception(ArithmeticException). // Appropriate Exception handler is not found within this method. static int divideByZero(int a, int b){ // this statement will cause ArithmeticException(/ by zero) int i = a/b; return i; } // The runTime System searches the appropriate Exception handler // in this method also but couldn't have found. So looking forward // on the call stack. static int computeDivision(int a, int b) { int res =0; try { res = divideByZero(a,b); } // doesn't matches with ArithmeticException catch(NumberFormatException ex) { System.out.println("NumberFormatException is occured"); } return res; } // In this method found appropriate Exception handler. // i.e. matching catch block. public static void main(String args[]){ int a = 1; int b = 0; try { int i = computeDivision(a,b); } // matching ArithmeticException catch(ArithmeticException ex) { // getMessage will print description of exception(here / by zero) System.out.println(ex.getMessage()); } } }
输出:
/ by zero.
定制异常处理: Java异常处理通过五个关键字进行管理:try,catch,throw,throws,final。简而言之,这就是他们的工作方式。您认为可能引发异常的程序语句包含在try块中。如果try块中发生异常,则会引发异常。你的代码可以捕获这个异常(使用catch块)并以合理的方式处理它。系统生成的异常由Java运行时系统自动抛出。要手动抛出异常,请使用关键字throw。任何抛出方法的异常都必须通过throws。在try块完成后绝对必须执行的任何代码都将放入finally块中。
需要try-catch子句(Customized Exception Handling)
考虑下面的Java程序。
// java program to demonstrate // need of try-catch clause class GFG { public static void main (String[] args) { // array of size 4. int[] arr = new int[4]; // this statement causes an exception int i = arr[4]; // the following statement will never execute System.out.println("Hi, I want to execute"); } }
输出:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 at GFG.main(GFG.java:9)
说明:在上面的例子中,数组是用大小来定义的,也就是说,你只能从索引0到3访问元素。但是你试图访问索引4处的元素(错误),这就是为什么它抛出一个异常。在这种情况下, JVM 异常终止程序。声明System.out.println(“嗨,我想执行”); 永远不会执行。为了执行它,我们必须使用try-catch来处理异常。因此,为了继续正常的程序流程,我们需要try-catch子句。
try{ //代码块来监视错误 / /你认为可以引发异常的代码 } catch(ExceptionType1 exOb){ // ExceptionType1的异常处理程序 } catch(ExceptionType2 exOb){ // ExceptionType2的异常处理程序 } // 可选的 finally { // try块结束后执行代码块 }
要记住的要点: