小言_互联网的博客

Java实验(5):异常

383人阅读  评论(0)

目录

Java异常

一、内容回顾

(一)Java异常的分类

(二)Java的异常处理

(三)自定义异常类

二、典型实例

三、实验设计

(一)实验一

(二)实验二


Java异常

一、内容回顾

    异常处理提供了一个统一的机制来识别和响应程序错误,一个有效的异常处理方法可以使得程序健壮并易于调试。在这一部分将介绍Java的异常机制,使用,以及如何定义自己的异常类。

(一)Java异常的分类

所有的Java异常都由Throwable继承下来,并在下一层产生两个分支:Error和Exception,如图1所示。

(1)Error类层次描述了Java运行时系统的内部错误和资源耗尽错误。应用程序不应该抛出这种类型的对象。如果出现这样的内部错误,能做的只有通知用户并尽力使程序安全终止。

(2)我们在设计Java程序的时候,重点关注Exception。Exception类层次结构又分解为两个分支,一个分支派生于RuntimeException,另一个包含其他异常。划分两个分支的规则是:由程序错误导致的异常属于RuntimeException(比如错误的类型转换,数组访问越界,访问空指针等);曾经能够正确运行,由于某些情况导致的异常则不属于RuntimeException(比如文件损坏,网络连接中断等)。

                                                                           图10-1 Java异常类层次结构图

另外,Java语言规范将派生于Error类和RuntimeException类的所有异常称为“未检查异常”,其他的异常称为“已检查异常”。如果程序出现了“未检查异常”,那么程序员应该尽力去排除程序的错误,而不是去捕获这类异常。

(二)Java的异常处理

  Java程序的执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常。当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常。如果Java运行时系统找不到可以捕获异常的方法,则运行时系统将终止,相应的Java程序也将退出。

  对于异常的处理,Java提供了两种方式

 (1)在方法中用try-catch-finally语句捕获并处理异常。catch语句可以有多个,用来匹配多个异常。finally是可选语句,为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理,通常用来释放各种资源。不论在try代码块中是否发生了异常事件,finally块中的语句都会被执行。


  
  1. try{
  2. ...... //可能产生异常的代码
  3. } catch( ExceptionName1 e ){
  4. ...... //当产生ExceptionName1型异常时的处置措施
  5. } catch( ExceptionName2 e ){
  6. ...... //当产生ExceptionName2型异常时的处置措施
  7. } [ finally{
  8. ...... //无条件执行的语句
  9. } ]

 (2)声明抛出异常是Java中处理异常的第二种方式,即在方法的声明处通过throws语句抛出异常。如果一个方法中的语句执行时可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。

  如果每个方法都是简单的抛出异常,那么在方法调用方法的多层嵌套调用中,Java虚拟机会从出现异常的方法代码块中往回找,直到找到处理该异常的代码块为止。然后将异常交给相应的catch语句处理。如果Java虚拟机追溯到方法调用栈最底部main()方法时,如果仍然没有找到处理异常的代码块,将首先调用异常的对象的printStackTrace()方法,打印方法调用栈的异常信息。如果出现异常的线程为主线程,则整个程序运行终止;如果非主线程,则终止该线程,其他线程继续运行。可以看出,越早处理异常消耗的资源和时间越小,产生影响的范围也越小。因此,尽量不要把自己能处理的异常也抛给调用者。

 

(三)自定义异常类

前面提到,Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出。如果Java内置的异常类不能够满足需求,也可根据需要人工创建并抛出异常。

人工创建并抛出异常,首先要生成异常对象,然后通过throw语句实现抛出操作(提交给Java运行环境)。另外,可以抛出的异常对象必须是Throwable或其子类的实例。我们自己定义的异常类必须派生于Exception或者Exception的子类。

 

二、典型实例

例1  本例实现的是求一个整数的阶乘,并对各种非正常情况捕获处理异常。


  
  1. // ExceptionTest.java
  2. public class ExceptionTest{
  3. public static double multi(int n){
  4. if(n< 0)
  5. throw new IllegalArgumentException( "求负数阶乘异常");
  6. double s= 1;
  7. for( int i= 1;i<=n;i++)
  8. s=s*i;
  9. return s;
  10. }
  11. public static void main(String[] args){
  12. try{
  13. int m=Integer.parseInt(args[ 0]);
  14. System.out.println(m+ "!="+multi(m));
  15. }
  16. catch (ArrayIndexOutOfBoundsException e){
  17. System.out.println( "命令行中没提供参数!");
  18. }
  19. catch (NumberFormatException e){
  20. System.out.println( "应输入一个整数!");
  21. }
  22. catch (IllegalArgumentException e){
  23. System.out.println( "出现的异常是:"+e.toString());
  24. }
  25. finally{
  26. System.out.println( "程序运行结束!");
  27. }
  28. }
  29. }

  程序执行结果如图2所示。

  说明:

  ①本例的运行需要有参数,参数赋值给args[0]。

 

图2 例1执行结果

 

 

  例2  本例测试如何人工抛出异常。


  
  1. // ThrowTest.java
  2. import java.util.Scanner;
  3. class MyException extends Exception {
  4. private int idnumber;
  5. public MyException(String message, int id) {
  6. super(message);
  7. this.idnumber = id;
  8. }
  9. public int getId() {
  10. return idnumber;
  11. }
  12. }
  13. public class ThrowTest{
  14. public void regist() throws MyException {
  15. Scanner sc = new Scanner(System.in);
  16. int num = sc.nextInt();
  17. if (num < 0) {
  18. throw new MyException( "人数为负值,不合理",num);
  19. }
  20. System.out.println( "登记人数" + num);
  21. }
  22. public void manager() {
  23. try {
  24. regist();
  25. } catch (MyException e) {
  26. System.out.println( "登记失败,出错种类"+e.getId());
  27. }
  28. System.out.print( "本次登记操作结束");
  29. }
  30. public static void main(String args[]){
  31. ThrowTest tt = new ThrowTest();
  32. tt.manager();
  33. }
  34. }

程序执行结果如图3所示。

说明:

①本例自定义了一个异常类MyException,如果输入的注册人数小于0,则人工抛出这个异常类的实例。

 

图3 例2执行结果

 

三、实验设计

(一)实验一

  (1)实验目的

    让学生掌握体会try-catch-finally语句的用法。

  (2)实验要求

    创建一个ThrowException类,该类有一个result() 方法,在result()方法内部有两个多项式A=4x-4,B=2*x*x-4*x*y+y*y,C=A/B,最后返回C的值。

  要求:x和y的值作为该方法的形参,在计算C值以前,先判断A和B的值,当A或B等于零时抛出一个ArithmeticException异常,使用ArithmeticException捕获该异常,在创建ArithmeticException异常时须使用其带形参的构造函数,给形参赋值为“A 或 B =0”,使用getMessage()显示该字符串。当A、B都不等于零时抛出一个Exception异常,使用Exception捕获该异常,在创建Exception异常时也须使用其带形参的构造函数,给形参赋值为“program is ok!”,使用getMessage()显示该字符串。最后不管A、B是否等于零,都须显示”program is end”(注:使用finally)。

  为这个类创建一个main()方法,生成两个20以内的整形随机数,调用result()方法,将这两个随机数赋给x和y,显示最后结果。

  (3)实验效果展示

    执行后的结果如图4所示。

 

图4 实验一效果展示

 

(二)实验二

  (1)实验目的

   让学生掌握体验自定义异常类的用法。

  (2)实验要求

   自定义类Triangle,其中有成员 x,y,z,作为三边长,构造方法triangle (a,b,c)分别给x,y,z赋值, getArea()方法用来求面积,showInfo()方法用来显示三角形信息(三个边长),这2个方法中当三条边不能构成一个三角形时要抛出自定义异常NotTriangleException,否则显示正确信息。在另外一个类中的主方法中构造一个Triangle对象(三边为命令行输入的三个浮点数),显示三角形信息和面积,要求捕获异常。

  (3)实验效果展示

   运行结果为图5所示。

图5实验二效果展示

  (4)实验指导

   ①参照例2来定义NotTriangleException。

 

 

 

 


转载:https://blog.csdn.net/Mark7758/article/details/106130556
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场