一、实验目的
本次实验的主要目的是练习使用
Java
语言异常处理方法,并掌握异常处理程
序的编写方法。
二、实验要求
1.
认真阅读实验内容,完成实验内容所设的题目
2.
能够应用多种编辑环境编写
JAVA
语言源程序
3.
认真体会异常处理的概念和方法
三、实验内容
1.
运行下列程序,观察程序的运行结果中出现异常
A、程序一
public class S61 { public static void main(String[] args) { int x = 0; if (x != 0) { System.out.println(5 / x); } else { System.out.println("除数不能为0"); } } }
问题:观察此程序出现什么异常,为什么出现这样的异常?
答:在这段代码中,会抛出一个 ArithmeticException
异常。这是因为在 System.out.println(5/x)
这行代码中,尝试将一个数除以0,这是一个不合法的操作,会导致算术运算异常。(简单来说就是除数不能为0的概念源于除法的定义)
B.程序二
public class S62 { public static void main(String [] args) { int [] s = new int[20]; for (int i = 0; i < s.length; i++) { s[i] = i; } } }
问题
:观察此程序出现什么异常,为什么出现这样的异常?
答:这段代码中,ArrayIndexOutOfBoundsException
会抛出一个 异常。这是因为在 for
循环中,使用了错误的索引范围,导致数组越界。在Java中,数组的索引范围是从0到数组长度减1,因此当使用 i<21
作为循环条件时,会导致 i
的值在循环执行到最后一次时为21,而数组的索引范围是0到19。因此当 i
的值为20时,会超出数组 s
的可用索引范围,引发 ArrayIndexOutOfBoundsException
异常。
C.程序三
public class S63 { public static void main(String [] args) { try { int j = 5 / 0; } catch(ArithmeticException e) { System.out.println("除零异常:" + e.toString()); } finally { System.out.println("end"); } } }
问题
:观察此程序出现什么异常,为什么出现这样的异常?
答:
因为尝试将一个数除以0,而在
catch
块中抓住了这个异常,并打印了异常的信息。最后无论是否发生异常,
finally
块中的代码都会被执行,并打印 "end"。
通过
try
块和
catch
块,程序可以捕获并处理可能发生的异常,以防止程序意外终止。
finally
块通常用于执行无论异常是否发生都需要被执行的代码,比如清理资源或者关闭文件等操作。
finally
块中的代码会在
try
块中发生异常时也被执行,确保无论发生什么情况,都会打印 "end"。这有助于保证程序在结束时执行必要的收尾工作。
D.程序四
public class S64 { public static void main(String [] args) { try { for(int i=0;i<10;i++) { if(i==9) throw new MyCustomException("Loop stopped at 9"); } } catch(MyCustomException e) { System.out.println(e.toString()); } } } class MyCustomException extends Exception { public MyCustomException(String message) { super(message); } }
问题
:观察此程序出现什么异常,为什么出现这样的异常?
答:
通过循环迭代变量
i
的值,当
i
的值等于9时,使用 throw new exc()
抛出了一个自定义的异常
exc
。在
catch
块中捕获了这个自定义异常,并打印了异常的信息。
注意
,在
exc
类的定义中,通过继承
Exception
类创建了一个自定义异常类。这种做法虽然可行,但不是常见的做法。通常情况下,异常应该用于处理预料之外的情况,而不是作为正常流程控制的一部分。抛出异常会对性能产生一定的消耗,因此不应该被频繁地用于正常的流程控制。
四、编写程序完成下列功能
1.
编写一个异常类
MyException
,再编写一个类
Student
,该类有一个产生异
常的方法
public void speak(int m) throws MyException
,要求参数
m
的值大于
1000
时,方法抛出一个
MyException
对象。最后编写主类,在主类的
main
方法中用
Student
创建一个对象,让该对象调用
speak
方法。
// 编写一个异常类MyException public class MyException extends Exception { public MyException(String message) { super(message); } } // 编写类Student public class Student { // 类Student有一个产生异常的方法speak public void speak(int m) throws MyException { if (m > 1000) { throw new MyException("参数m的值大于1000"); } } } // 编写主类 public class Main { public static void main(String[] args) { // 在主类的main方法中用Student创建一个对象,让该对象调用speak方法 Student student = new Student(); try { student.speak(1500); } catch (MyException e) { System.out.println(e.getMessage()); } } }
2.
自定义类
Sanj
,其中有成员
x,y,z,
作为三边长,构造方法
Sanj(a,b,c)
分别给
x,y,z
赋值
,
方法求面积
getArea
和显示三角形信息
(
三个边长
)showInfo
,这
2
个方法
中当三 条边丌能构成一个三角形时要抛出自定义异常
NotSanjiaoException
,否则
显示正确信 息。在另外一个类中的主方法中构造一个
Sanj
对象
(
三边为命令行输
入的三个整数
)
, 显示三角形信息和面积,要求捕获异常。
import java.util.Scanner; // 自定义异常类 class NotSanjiaoException extends Exception { public NotSanjiaoException(String message) { super(message); } } // 自定义三角形类 class Sanj { private int x, y, z; // 构造方法 public Sanj(int a, int b, int c) { x = a; y = b; z = c; } // 求面积方法 public double getArea() { double p = (x + y + z) / 2.0; return Math.sqrt(p * (p - x) * (p - y) * (p - z)); } // 显示三角形信息方法 public void showInfo() throws NotSanjiaoException { if (x + y <= z || x + z <= y || y + z <= x) { throw new NotSanjiaoException("无法构成三角形"); } else { System.out.println("三角形的三边长分别为:" + x + ", " + y + ", " + z); } } } public class Main { public static void main(String[] args) { try { Scanner scanner = new Scanner(System.in); System.out.println("请输入三角形的三个边长:"); int a = scanner.nextInt(); int b = scanner.nextInt(); int c = scanner.nextInt(); Sanj sanj = new Sanj(a, b, c); sanj.showInfo(); System.out.println("三角形的面积为:" + sanj.getArea()); } catch (NotSanjiaoException e) { System.out.println("发生异常:" + e.getMessage()); } } }
五、实验总结
在实验中,我遇到了一些问题,例如如何选择合适的异常类型以及如何正确地捕获和处理异常。通过不断实践和调试,我逐渐掌握了异常处理的技巧,并且能够更好地应对各种异常情况。在以后的编程实践中,我将继续加强对异常处理的理解和应用,以提高代码的稳定性和可靠性。