Java异常处理实例分析

 更新时间:2015年04月16日 15:30:48   作者:司青  
这篇文章主要介绍了Java异常处理,实例分析了java异常处理的常见用法,具有一定参考借鉴价值,需要的朋友可以参考下

本文实例讲述了Java异常处理的用法。分享给大家供大家参考。具体分析如下:

Java的异常处理机制可以帮助我们避开或者处理程序可能发生的错误,从而使得程序在遇到一些可恢复的错误的时候不会意外终止,而是去处理这些错误,也使得我们在写程序的时候不必写大量的代码来检查错误情况,增强了代码的可读性和逻辑性。在Java中,异常代表一个错误的实体对象。

异常可分为两类;一类是严重错误,如硬件错误、内存不足等,它们对应着java.lang包下的Error类及其子类。通常这类错误程序自身是无法恢复的,需要中断程序的执行;另一类是非严重的错误,如用户输入了非法数据,被0除等,它们对应着java.lang包中的Exception类及其子类,这种错误一般可以恢复,不影响程序的运行。
我们可以用try, catch,finally关键字来捕捉异常。

1、try, catch

将可能会发生异常的语句放到try{}块中,然后在catch{}语句块中捕捉即可。如被0除异常:

public class SimpleDemo 
{ 
  //除法运算 
  public static int devision(int a,int b) 
  { 
    return a / b; 
  } 
   
  public static void main(String[] args) 
  { 
    try  
    { 
      //5除以0 
      SimpleDemo.devision(5,0); 
      System.out.println("Exception"); 
    }  
    catch (Exception e)  
    { 
      e.printStackTrace(); 
    } 
     
    System.out.println("Finish"); 
  } 
}

执行结果:

可以看到,Finish被打印了出来,说明程序并没有因为发生了被0除的错误而终止。
同时我们也发现,发生异常的SimpleDemo.devision()下面的System.out.println语句并没有被执行。一旦异常发生,程序就会从当前执行的位置跳出,而不会执行异常后面的语句。

2、finally

finally语句块中的语句无论异常有没有发生都会被执行。
有人可能会问,既然finally块中的语句无论异常有没有发生都会被执行,那么这个finally到底有什么实际作用呢?我不用finally直接写在外面不行么?
如上例,我们在catch语句块中加入一个return:

public class SimpleDemo 
{ 
  //除法运算 
  public static int division(int a,int b) 
  { 
    return a / b; 
  } 
  public static void main(String[] args) 
  { 
    try  
    { 
      //5除以0 
      SimpleDemo.division(5,0); 
      System.out.println("Exception"); 
    }  
    catch (Exception e)  
    { 
      e.printStackTrace(); 
      return; //main函数返回 
    } 
    finally 
    { 
      System.out.println("Finally"); 
    } 
    System.out.println("Finish"); 
  } 
}

这时候,finally外面的Finish没有被打印,而finally块内部的Finally则被打印了出来。

finally在实际开发中非常有用。例如我们打开了一个数据库,在数据库读写数据的时候发生了异常,那么这时候就应该关闭数据库的连接,并释放相应的资源。这时候把释放资源的代码写在 finally块中是最合适不过的了。

但要注意的是,finally块在一种情况下是不会被执行的。如果程序在执行到finally块前退出了,如调用System.exit()方法,则 finally块也就得不到执行的机会了。

3、丢出异常

如果在一个方法中会有异常发生,但我们不想在方法中直接去处理这个异常,而是想让方法的调用者去处理,则可以使用throws关键字声明这个方法来丢出异常。这在Sun给我们提供的API函数中非常常见,如java.io.Reader中的read方法被声明为丢出一个IOException异常:

public int read(char[] cbuf)
     throws IOException

这时候我们在调用read方法时就必须将其放在try语句块中进行异常捕捉,否则编译器就会报错,强制我们进行异常捕捉。
当然,如果我们确实不想在调用read的时候处理异常,那么也可以把调用read方法的方法声明为throws IOException,这样异常就会再次被丢出。如果我们在main函数中声明丢出Exception异常,那么异常信息最终会被JVM捕获处理,而JVM的处理结果是,打印出异常信息,然后终止程序的运行。

4、异常处理的构架

所有的异常类都是从Exception类中派生而来的。这意味着,如果我们不确定会发生什么类型的异常,可以直接在catch中声明一个Exception对象,就能捕获到所有的Exception类及其子类的异常了。但要注意catch书写的顺序。如果在一个try后面有多个catch且第一个catch中声明的是Exception对象,那么这个异常就会直接被第一个catch处理,后面的catch都无法捕获到这个异常。这种错误在编译的时候就会以产生错误。如下例:

public class CatchDemo 
{ 
  //除法运算 
  public static int division(int a,int b) 
  { 
    return a / b; 
  } 
  public static void main(String[] args) 
  { 
    try 
    { 
      CatchDemo.division(4,0); 
    } 
    catch(Exception e) 
    { 
      System.out.println("Exception Class"); 
    } 
    catch(ArithmeticException e) 
    { 
      System.out.println("ArithmeticException Class"); 
    } 
  } 
}

编译器输出  ArithmeticException已经被捕获了,意思就是说上面的Exception已经捕获了这个异常,无须重复捕获。

如果把这两个catch反过来会怎样呢?

public class CatchDemo 
{ 
  //除法运算 
  public static int division(int a,int b) 
  { 
    return a / b; 
  } 
  public static void main(String[] args) 
  { 
    try 
    { 
      CatchDemo.division(4,0); 
    } 
    catch(ArithmeticException e) 
    { 
      System.out.println("ArithmeticException Class");
    } 
    catch(Exception e) 
    { 
      System.out.println("Exception Class");
    } 
  } 
}

这时候我们发现,代码通过了编译,且执行的结果是 ArithmeticException捕获了这个异常,而后面的catch则没有捕获到。

希望本文所述对大家的java程序设计有所帮助。

相关文章

  • Windows系统下Java连接SQL Server的方法简介

    Windows系统下Java连接SQL Server的方法简介

    这篇文章主要介绍了Windows系统下Java连接SQL Server的方法,分别是JDBC和JTDS的相关使用,需要的朋友可以参考下
    2015-09-09
  • Java实现斗地主案例

    Java实现斗地主案例

    这篇文章主要为大家详细介绍了Java实现斗地主案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • Arrays.sort(arr)是什么排序及代码逻辑

    Arrays.sort(arr)是什么排序及代码逻辑

    在学习过程中观察到Arrays.sort(arr)算法可以直接进行排序,但不清楚底层的代码逻辑是什么样子,今天通过本文给大家介绍下Arrays.sort(arr)是什么排序,感兴趣的朋友一起看看吧
    2022-02-02
  • Java多线程编程综合案例详解

    Java多线程编程综合案例详解

    这篇文章将通过三个案例带大家了解一下Java中的多线程编程,文中的示例代码介绍详细,对我们的学习或工作有一定的价值,感兴趣的小伙伴可以了解一下
    2022-07-07
  • 一篇文章让你彻底了解Java可重入锁和不可重入锁

    一篇文章让你彻底了解Java可重入锁和不可重入锁

    最近正在阅读Java ReentrantLock源码,始终对可重入和不可重入概念理解不透彻,今天特地整理了本篇文章,让你彻底了解Java可重入锁和不可重入锁,需要的朋友可以参考下
    2021-06-06
  • 基于mybatis逆向工程的使用步骤详解

    基于mybatis逆向工程的使用步骤详解

    下面小编就为大家带来一篇基于mybatis逆向工程的使用步骤详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • Mybatis(ParameterType)传递多个不同类型的参数方式

    Mybatis(ParameterType)传递多个不同类型的参数方式

    这篇文章主要介绍了Mybatis(ParameterType)传递多个不同类型的参数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • Javaweb实现在线人数统计代码实例

    Javaweb实现在线人数统计代码实例

    这篇文章主要介绍了Javaweb实现在线人数统计代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • SpringBoot中Redis的缓存更新策略详解

    SpringBoot中Redis的缓存更新策略详解

    这篇文章主要介绍了SpringBoot中Redis的缓存更新策略,缓存一般是为了应对高并发场景、缓解数据库读写压力,而将数据存储在读写更快的某种存储介质中(如内存),以加快读取数据的速度,需要的朋友可以参考下
    2023-08-08
  • Java中获取类路径classpath的简单方法(推荐)

    Java中获取类路径classpath的简单方法(推荐)

    下面小编就为大家带来一篇Java中获取类路径classpath的简单方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09

最新评论