zoukankan      html  css  js  c++  java
  • Java中的异常报告和处理机制

    为了应对运行期间可能出现的错误,提高程序的的稳健性,Java中定义了强大的异常处理机制。

    Java的异常机制在增强程序稳健性的同时(围绕异常声明,在编译期间就具有严格的异常制度),增强了业务代码的逻辑性和连贯性(通过try-catch,避免了C等语言下的业务逻辑代码和异常检测代码严重混合)。

    异常声明:Java要求能抛出异常的方法必须加上异常声明(该些异常未被处理,且非Java中定义的标准异常)。

    Example:

     1 package demo;
     2 import static net.mindview.util.Print.*;
     3 
     4 public class TestException {
     5     TestException(int i) throws ExceptionA,ExceptionB{
     6         switch(i)
     7         {
     8         case 1 : throw new ExceptionA();
     9         case 2 : throw new ExceptionB();
    10         default : {int a[]={0,}; a[1]=1;};
    11         }
    12     }
    13 }
    14 class ExceptionA extends Exception{};
    15 class ExceptionB extends Exception{};
     1 package demo;
     2 
     3 import net.mindview.*;
     4 import net.mindview.util.PackageTest;
     5 
     6 import java.util.Arrays;
     7 import java.util.Random;
     8 
     9 import static net.mindview.util.Print.*;
    10 
    11 import static net.mindview.util.Range.*;
    12 
    13 import trypackage.*;
    14 
    15 public class printtry {
    16 
    17     /**
    18      * @param args
    19      */
    20     public static void main(String[] args) {
    21         for(int i=0;i<=3;i++)
    22         {
    23             try{
    24                 print("Test:"+Integer.toString(i));
    25                 TestException testException=new TestException(i);
    26                 }
    27                 catch(ExceptionA e)
    28                 {
    29                     print("Catch the exception from:A cathcing block");
    30                     e.printStackTrace();
    31                 }
    32                 catch(ExceptionB e)
    33                 {
    34                     print("Catch the exception from:B catching block");
    35                     e.printStackTrace();
    36                 }
    37                 catch(Exception e)
    38                 {
    39                     print("Catch the exception from:others catching block ");
    40                     e.printStackTrace();
    41     
    42                 }
    43                 finally
    44                 {
    45                     print("The finally block must be executed!");
    46                 }
    47         }
    48         
    49 
    50     }
    51 
    52 }

    运行结果:

    从Example 中可以发现:

    1、异常声明极其重要性

    异常声明:即用户必须将函数可能抛出的所有自定义异常(即非标准异常),添加到函数声明中。

    TestException(int i) throws ExceptionA,ExceptionB 方法(为TestException类的构造方法),由于其函数体中会抛出ExceptionA和ExceptionB两类用户自定义的异常,故必须在其函数声明中添加异常声明:throws ExceptionA,ExceptionB,否则Java无法让该文件编译通过。

    你可能会注意到:default : {int a[]={0,}; a[1]=1;};该语句会产生明显的数组访问下标越界异常,但是却未将其添加到函数的异常声明中。这是因为此异常属于Java中自定义的非标准异常,其会自动的被逐层上报给main()函数(若上报的过程中未被try-catch处理)。

    Java为什么要求异常声明?

    这正是Java相比于C等语言的独特之处,Java的异常声明给编译器提供了一个非常重要的信息,即:该方法会产生哪些异常

    一旦编译器可以确定方法体会产生的异常,那么当该方法被置于try块中时,编译器就会强制的要求所有的异常都要能被catch处理

    若以上的的程序改为:

    for(int i=0;i<=3;i++)
    		{
    			try{
    				print("Test:"+Integer.toString(i));
    				TestException testException=new TestException(i);
    				}
    				catch(ExceptionA e)
    				{
    					print("Catch the exception from:A cathcing block");
    					e.printStackTrace();
    				}
    				finally
    				{
    					print("The finally block must be executed!");
    				}
    		             }
    		
    
    	         }
    

    该程序将无法被编译通过,因为编译器通过方法的异常声明TestException(int i) throws ExceptionA,ExceptionB已经得知:TestException会抛出ExceptionA和ExceptionB两类异常,而此处的catch模块只给出了catch(ExceptionA e),即ExceptionB被没有被处理。这也正是Java竭力设计出异常机制,以保证程序健壮性的原因。

    注意:Java此处只是提供了一种检查机制(提醒机制),至于异常能否被处理或者能否被妥善的处理,完全由程序员所决定。程序员也许为了编译让的通过会写出:

    catch(ExceptionB e)
    				{
    
    				}
    

    此处虽然catch了ExceptionB,并且保证了程序能够顺利的编译通过,但是程序员却对此异常什么也没做!

    看上去好像并没有起到处理异常的作用? 确实如此,程序员未给出任何的处理办法,一旦相应的异常产生,无应对措施!

    但是这完全是由使用该方法的程序员所造成的,Java已经通过自己的检查机制提醒了程序员需要的异常处理,已经起到了增强程序健壮性的作用!

    起码让程序知道了这里有一个必须处理的异常,至于是否处理,如何处理,已经不是编译能够控制的事情。

     

    2、异常类的继承和处理机制。

    下一个程序却能编译通过:为什么程序中未给出ExceptionB的catch处理,但是仍然能够编译通过。

    		for(int i=0;i<=3;i++)
    		{
    			try{
    				print("Test:"+Integer.toString(i));
    				TestException testException=new TestException(i);
    				}
    				catch(ExceptionA e)
    				{
    					print("Catch the exception from:A cathcing block");
    					e.printStackTrace();
    				}
    				catch(Exception e)
    				{
    					print("Catch the exception from:others catching block ");
    					e.printStackTrace();
    	
    				}
    				finally
    				{
    					print("The finally block must be executed!");
    				}
    		}
    		
    
    	}
    

    这是因为添加了catch(Exception a)模块,使得所有的异常都能被catch。这是为什么呢?

    因为Exception是所有异常类的基类,包括Java中的常规异常:

    class ExceptionA extends Exception{};
    class ExceptionB extends Exception{};
    

    catch模块会对try中捕获到的异常对象(一次只可能产生一个异常对象),依次的进行匹配,一旦匹配成功即转入catch块中进行相应的处理。

    在匹配的过程中,如果catch声明的为基类异常对象,那么其导出类的异常对象是可以被其正常捕获的,即自动实现了向上的转型

    Exception类为所有异常类的基类,故编译器认为ExceptionB对象能被catch,所以没有产生编译错误。

    重要: catch(Exception e){}又被称为捕获全部异常对象,常常用于放在最后一个catch中,保证所有意料之外的异常对象都能被捕获。

    	catch(Exception e)
    				{
    					print("Catch the exception from:others catching block ");
    					e.printStackTrace();
    	
    				}
    

    catch(Exception e)虽然能捕获所有异常对象,但是其处理方法却只能有一种,无针对性,对任何意料之外的异常都要适用。所以其处理方法一般为将捕获的异常对象的信息通过e.printStackTrace()方法输出到控制台,以提醒程序员何种意料之外的异常发生了。

    机制:对于同一个try块,Java不允许catch(基类)出现在catch(相应导出类)之前,以覆盖了更好的异常处理方法。

     

     

     

     

     

     

     

     

  • 相关阅读:
    hdu5081
    hdu5079
    hdu5076
    hdu5072
    codeforces 739E
    codeforces 739D
    2017.2其他简要题解
    spring事务传播回滚策略
    mybatis一级缓存和二级缓存
    spring-boot-mybatis-starter工作原理
  • 原文地址:https://www.cnblogs.com/airwindow/p/2563876.html
Copyright © 2011-2022 走看看