Java实验(5):异常

目录

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块中的语句都会被执行。

try{

...... //可能产生异常的代码

}catch( ExceptionName1 e ){

...... //当产生ExceptionName1型异常时的处置措施

}catch( ExceptionName2 e ){

...... //当产生ExceptionName2型异常时的处置措施

}  [ finally{

......  //无条件执行的语句

    }  ]

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

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

 

(三)自定义异常类

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

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

 

二、典型实例

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

// ExceptionTest.java

public class ExceptionTest{

   public static double multi(int n){

      if(n<0)

         throw new IllegalArgumentException("求负数阶乘异常");

      double s=1;

      for(int i=1;i<=n;i++)

         s=s*i;

      return s;

   }

  public static void main(String[] args){

      try{

         int m=Integer.parseInt(args[0]);

         System.out.println(m+"!="+multi(m));  

      }

      catch (ArrayIndexOutOfBoundsException e){

         System.out.println("命令行中没提供参数!");

      }

      catch (NumberFormatException e){

         System.out.println("应输入一个整数!");

      }

      catch (IllegalArgumentException e){

         System.out.println("出现的异常是:"+e.toString());

      }

      finally{

         System.out.println("程序运行结束!");

      }

    }

}

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

  说明:

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

 

图2 例1执行结果

 

 

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

// ThrowTest.java

import java.util.Scanner;

class MyException extends Exception {

       private int idnumber;

   public MyException(String message, int id) {

       super(message);

       this.idnumber = id;

   }

   public int getId() {

       return idnumber;

   }

}

public class ThrowTest{

     public void regist() throws MyException {

       Scanner sc = new Scanner(System.in);

       int num = sc.nextInt();

       if (num < 0) {

             throw new MyException("人数为负值,不合理",num);

       }

       System.out.println("登记人数" + num);

     }

     public void manager() {

       try {

              regist();

        } catch (MyException e) {

              System.out.println("登记失败,出错种类"+e.getId());      

        }

       System.out.print("本次登记操作结束");

     }

     public static void main(String args[]){

       ThrowTest tt = new ThrowTest();

       tt.manager();

       }

}

程序执行结果如图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 实验一效果展示

参考实验代码

//ThrowException.java
import java.util.Random;

public class ThrowException{
	static double A,B,C = 0;
	static double result(int x,int y){
		A = 4*x - 4;
		B = 2*x*x - 4*x*y + y*y;
		try{
			if(A == 0||B == 0){
				throw new ArithmeticException("A或B=0");
			}
			else{
				throw new Exception("Program is OK!");
			}
		}
		catch(ArithmeticException e){
			System.out.println(e.getMessage());
		}
		catch(Exception e){
			System.out.println(e.getMessage());
			C = A/B;
		}
		finally{
			System.out.println("A = "+A);
			System.out.println("B = "+B);
			System.out.println("C = "+C);
			System.out.println("Program is end.");
			return C;
		}
	}


	public static void main(String[] args){
		Random a = new Random();
		int x = a.nextInt(20);
		int y = a.nextInt(20);
		System.out.println("x = "+x);
		System.out.println("y = "+y);
		result(x,y);
	}
}

运行结果

(二)实验二

  (1)实验目的

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

  (2)实验要求

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

  (3)实验效果展示

   运行结果为图5所示。

图5实验二效果展示

  (4)实验指导

   ①参照例2来定义NotTriangleException。

参考实验代码

//TriangleException.java
import java.util.Scanner;

class Triangle{
	double x,y,z;
	public Triangle(double x,double y,double z){
		this.x = x;
		this.y = y;
		this.z = z;
	}
	public double getArea(){
		double area = 0;
		double p = (x+y+z)/2.0;
		area = Math.sqrt(p*(p-x)*(p-y)*(p-z));
		return area;
	}
	public void showInfo(){
		try{
			if(x+y>z&&x+z>y&&y+z>x){
				System.out.println("边长分别为:"+ String.format("%.2f,%.2f,%.2f",x,y,z));//+x+","+y+","+z);
			}
			else{
				throw new NoTriangleException("不能构成三角形!");
			}
		}
		catch(NoTriangleException e){
				System.out.println(e.getMessage());
		}
	}
}

class NoTriangleException extends Exception{
	NoTriangleException(String s){
		super(s);
	}
}

public class TriangleException{
	public static void main(String[] args){
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入三边长:");
		double x = scanner.nextInt();
		double y = scanner.nextInt();
		double z = scanner.nextInt();
		Triangle triangle = new Triangle(x,y,z);
		double area = triangle.getArea();
		if(x+y>z&&x+z>y&&y+z>x)
			System.out.println("三角形面积是"+area);
		triangle.showInfo();
	}
}

运行结果

 

 

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值