什么是异常?
异常是一个不需要的或意外的事件,它发生在程序执行过程中,即在运行时发生,这会中断程序指令的正常流程。
错误与异常
错误: 错误表示合理应用程序不应尝试捕捉的严重问题。
异常: 异常表示合理应用程序可能尝试捕获的条件。
异常层次结构
所有异常和错误类型都是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块结束后执行代码块
}
要记住的要点: