1. 什么是Java异常?
java异常是指在Java程序运行期间,碰到的一些非预期的事件,这些非预期的时间会导致程序非正常终止。
2. Exception和Error的区别和联系
区别:
exception
:可以捕获error
:无法捕获
联系:
exception
和error
都是继承Throwable
3. java程序是如何处理异常的?
在Java程序中,任何一个方法发生了异常,这个方法就会创建一个异常对象,然后将这个异常对象交给JVM处理,这个过程被称为抛出异常。异常对象包含了异常名称,异常信息,以及异常发生了位置。有时候,发生异常的方法是由方法A调用,方法A又由方法B调用,以此类推。那么,按照这些方法的先后执行顺序所组成的栈被称为异常栈(Call Stack)。抛出异常以后,JVM是怎么处理异常的呢?
- JVM会根据异常栈,由上往下,寻找对应的handler。所谓的handler,就是能捕获并解决对应异常的代码块。这个代码块被称为Exception Handler;
- 需要注意的是,栈是先进后出的,所以,JVM所查找的顺序与方法的调用顺序相反;
- 如果找到了可以解决异常的Exception Handler,那么就会解决异常,并继续执行程序;
- 如果无法找到Exception Handler,那么JVM会有一个默认的Default Exception Handler来处理异常,这个Default Exception Handler会打印异常信息(异常名称,异常信息,异常栈)以及非正常的终止程序。
下面这个图就是异常栈的形成过程:
4. 一个简单的异常的例子
// 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)
//这里b = 0,抛出异常,JVM根据异常栈找到了computeDivision()方法
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
{
//这里并没有可以解决异常的Handler,因为发生的异常并不是NumberFormatException
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
{
//JVM根据异常栈找到这里,这里由解决异常的handler(catch代码块,后面会解释),异常在这里被解决。程序继续运行。
int i = computeDivision(a,b);
}
// matching ArithmeticException
catch(ArithmeticException ex)
{
// getMessage will print description of exception(here / by zero)
System.out.println(ex.getMessage());
}
}
}
5. 程序员如何解决异常
与异常有关的关键字,一共有5个:try, catch, finally, throw, throws
try
:用于存放可以能出现的异常的代码;catch
:用于捕获异常。我们上面说到,异常会被抛出,然后由JVM尝试去寻找handler,这里的catch
就是handler;finally
:不管有没有发生异常,异常有没有被解决,finally
中的代码都会被执行;throw
:用于抛出异常;throw
:用于抛出异常(方法用)。
示例代码:
public class JavaException {
//throws,用于方法抛出异常
static void divide(int a, int b) throws ArithmeticException{
try {
//b为0时,可能发生异常,因此放在try中
int result = a / b;
System.out.println(result);
} catch (ArithmeticException e) {
//catch捕获异常,但是这里又用throw将异常抛出
throw e;
} finally {
System.out.println("finally block");
}
}
public static void main(String[] args) {
int a = 1;
int b = 0;
try {
divide(1, 0);
} catch (ArithmeticException e) {
System.out.println("Can not divide by 0!");
}
}
}
最后留一道的思考题,main方法中没有try…catch代码块,程序运行的结果会是怎么样的?
参考:https://www.geeksforgeeks.org/exceptions-in-java/