Java中的异常和处理详解(2)

----欢迎使用命令行除法计算器----
2
0
Exception in thread "main" java.lang.ArithmeticException : / by zero
    at com.example.AllDemo.devide( AllDemo.java:30 )
    at com.example.AllDemo.CMDCalculate( AllDemo.java:22 )
    at com.example.AllDemo.main( AllDemo.java:12 )

----欢迎使用命令行除法计算器----
1
r
Exception in thread "main" java.util.InputMismatchException
    at java.util.Scanner.throwFor( Scanner.java:864 )
    at java.util.Scanner.next( Scanner.java:1485 )
    at java.util.Scanner.nextInt( Scanner.java:2117 )
    at java.util.Scanner.nextInt( Scanner.java:2076 )
    at com.example.AllDemo.CMDCalculate( AllDemo.java:20 )
    at com.example.AllDemo.main( AllDemo.java:12 )
*****************************************/

异常是在执行某个函数时引发的,而函数又是层级调用,形成调用栈的,因为,只要一个函数发生了异常,那么他的所有的caller都会被异常影响。当这些被影响的函数以异常信息输出时,就形成的了异常追踪栈

异常最先发生的地方,叫做异常抛出点

Java中的异常和处理详解

从上面的例子可以看出,当devide函数发生除0异常时,devide函数将抛出ArithmeticException异常,因此调用他的CMDCalculate函数也无法正常完成,因此也发送异常,而CMDCalculate的caller——main 因为CMDCalculate抛出异常,也发生了异常,这样一直向调用栈的栈底回溯。这种行为叫做异常的冒泡,异常的冒泡是为了在当前发生异常的函数或者这个函数的caller中找到最近的异常处理程序。由于这个例子中没有使用任何异常处理机制,因此异常最终由main函数抛给JRE,导致程序终止。

上面的代码不使用异常处理机制,也可以顺利编译,因为2个异常都是非检查异常。但是下面的例子就必须使用异常处理机制,因为异常是检查异常。

代码中我选择使用throws声明异常,让函数的调用者去处理可能发生的异常。但是为什么只throws了IOException呢?因为FileNotFoundException是IOException的子类,在处理范围内。

@Test
public void testException() throws IOException
{
    //FileInputStream的构造函数会抛出FileNotFoundException
    FileInputStream fileIn = new FileInputStream("E:\\a.txt");
   
    int word;
    //read方法会抛出IOException
    while((word =  fileIn.read())!=-1)
    {
        System.out.print((char)word);
    }
    //close方法会抛出IOException
    fileIn.clos
}

异常处理的基本语法

在编写代码处理异常时,对于检查异常,有2种不同的处理方式:使用try...catch...finally语句块处理它。或者,在函数签名中使用throws 声明交给函数调用者caller去解决。

try...catch...finally语句块

try{
    //try块中放可能发生异常的代码。
    //如果执行完try且不发生异常,则接着去执行finally块和finally后面的代码(如果有的话)。
    //如果发生异常,则尝试去匹配catch块。

}catch(SQLException SQLexception){
    //每一个catch块用于捕获并处理一个特定的异常,或者这异常类型的子类。Java7中可以将多个异常声明在一个catch中。
    //catch后面的括号定义了异常类型和异常参数。如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常。
    //在catch块中可以使用这个块的异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问。
    //如果当前try块中发生的异常在后续的所有catch中都没捕获到,则先去执行finally,然后到这个函数的外部caller中去匹配异常处理器。
    //如果try中没有发生异常,则所有的catch块将被忽略。

}catch(Exception exception){
    //...
}finally{
 
    //finally块通常是可选的。
  //无论异常是否发生,异常是否匹配被处理,finally都会执行。
  //一个try至少要有一个catch块,否则, 至少要有1个finally块。但是finally不是用来处理异常的,finally不会捕获异常。
  //finally主要做一些清理工作,如流的关闭,数据库连接的关闭等。
}

需要注意的地方

1、try块中的局部变量和catch块中的局部变量(包括异常变量),以及finally中的局部变量,他们之间不可共享使用。

 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/fd943d721d71b253d14f8abf5b2c70c3.html