一、实验目的
了解JAVA中异常处理的作用及常用的异常类,掌握异常处理的设计方法。
二、实验内容
1、用try-catch-finally结构实现异常处理。编译并运行程序,写出运行结果。
2、设计一个Java程序,自定义异常类,从命令行(键盘)输入一个字符串, 如果该字符串值为“XYZ”,则抛出一个异常信息“This is a XYZ”,如果从命令行输入 ABC,则没有抛出异常。(只有 XYZ 和 ABC 两种输入)。
3、声明一个 Average 接口,继续完善学生信息录入程序,其中约定求平均 值的方法;声明多个类实现 Average 接口,分别给出求平均值的方法实现。例如,在一组数值中,一种算法是,全部数值相加后求平均值,另一种算法是,去掉一个最高分和一个最低分后,再将总分求平均等;使用键盘输入数据时,对于不能转换成数值的字符串进行异常处理。
三、实验程序源代码
1、
public class ExceptionTest
{
public static void main(String args[])
{
int i=0;
String greeting[]={"Hello","Only","Test"};
while(i<4)
{
try
{
System.out.println(greeting[i]);
}catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("数组越界");
}
finally
{
System.out.println("总能运行");
}
i++;
}
}
}
2、
import java.lang.Exception;
import java.util.Scanner;
class CharException extends Exception{
private String kkk;
public CharException(String k){
kkk=k;
}
public String getChar(){
return(kkk);
}
}
class Cha{
public String str1;
public Cha(String str1){
this.str1=str1;
}
public String isXYZ(String s) throws CharException
{
if(s.equals("XYZ")){
throw new CharException("This is XYZ"); //throw语句抛出异常
}
else{
return str1;
}
}
public static void main(String[] args)
{
Scanner scan=new Scanner(System.in);
System.out.print("请输入一个字符串:");
String m=scan.nextLine();
System.out.println(m);
Cha t=new Cha(m);
try{
t.isXYZ(m);
}
catch(CharException e){
System.out.println(e.getChar());
}
scan.close();
}
}
3、
import java.util.*;
import java.lang.Exception;
interface Average{
public abstract int Average_age();
public abstract double Average_score();
}
class MyDate{
public int year;
public int month;
public int day;
public MyDate(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
}
public static boolean isLeapyear(int year){
return (year%400==0)||(year%100!=0&&year%4==0);
}
public static int Dayofmonth(int year,int month){
switch(month){
case 1:case 3:case 5:case 7:case 8:case 10:case 12: return 31;
case 2: return MyDate.isLeapyear(year)?29:28;
case 4:case 6:case 9:case 11: return 30;
default: return 0;
}
}
public static boolean isValidDate(int year,int month,int day){
return (year>0&&year<=2022)&&(month>0&&month<=12)&&(day>0&&day<=Dayofmonth(year,month));
}
}
class Average1 extends MyDate implements Average{
public String name;//姓名
public String Sno;//学号
public String ID;//身份证号
public String sex;//性别
public int age;//年龄
public double score;//JAVA实验成绩
Average1(String n,String sno,String id,String sex,int a,double s,int year,int month,int day){
super(year,month,day);
name=n;
Sno=sno;
this.sex=sex;
age=a;
score=s;
}
public int Average_age(){
return 0;
}
public double Average_score(){
return 0;
}
public static void main(String args[]){
ArrayList<MyDate> stu=new ArrayList<>();
Scanner scan=new Scanner(System.in);
System.out.print("输入学生的数目:");
int n=scan.nextInt();
String name,ID,Sno,sex;
int age[]=new int[n];
double score[]=new double[n];
int year,month,day;
int total_age=0;
double total_score=0.0;
System.out.println("输入学生信息: 姓名 身份证号 学号 性别 年龄 JAVA实验成绩 出生时间");
for(int i=0;i<n;i++){
try{
name=scan.next();
ID=scan.next();
Sno=scan.next();
sex=scan.next();
age[i]=scan.nextInt();
score[i]=scan.nextDouble();
year=scan.nextInt();
month=scan.nextInt();
day=scan.nextInt();
}
catch(Exception ee){
System.out.println("输入数据格式错误,请重新输入");
continue;
}
stu.add(new MyDate(year,month,day));
if(!stu.get(i).isValidDate(year,month,day)){
System.out.println("生日日期无效");
}
else{
System.out.println("生日日期时闰年吗?"+stu.get(i).isLeapyear(year));
if(stu.get(i).Dayofmonth(year,month)==31)
System.out.println("生日日期月份是大月");
else if(stu.get(i).Dayofmonth(year,month)==30)
System.out.println("生日日期月份是小月");
else if(stu.get(i).Dayofmonth(year,month)==29||stu.get(i).Dayofmonth(year,month)==28){
System.out.println("生日日期既不是大月也不是小月,是二月");
}
}
}
Arrays.sort(age);
Arrays.sort(score);
System.out.println("输出排序后的学生年龄:"+Arrays.toString(age));
System.out.println("输出排序后的学生成绩:"+Arrays.toString(score));
System.out.println("计算学生的平均年龄和平均成绩有两种方法: ");
while(true){
System.out.println("输入数字: 按1进入第一种方法:全部数值相加求平均值 按2进入第二种方法:去掉最大最小值求平均值");
int a=scan.nextInt();
switch(a){
case 1:{
for(int j=0;j<n;j++){
total_age+=age[j];
total_score+=score[j];
}
System.out.println("学生的平均年龄为:"+total_age/n);
System.out.println("学生的平均成绩为:"+String.format("%.2f",total_score/n));
break;
}
case 2:{
for(int j=1;j<n-1;j++){
total_age+=age[j];
total_score+=score[j];
}
System.out.println("学生的平均年龄为:"+total_age/(n-2));
System.out.println("学生的平均成绩为:"+String.format("%.2f",total_score/(n-2)));
break;
}
default: System.exit(0);
}
}
}
}
四、实验结果
1、运行结果
2、运行结果
3、
(1)第一种计算平均值的方法:全部数值相加后求平均值
(2)第二种计算平均值的方法:去掉最高值和最低值再计算平均值
(3)改善输出方式之后输入的另一组数据:
(4)继续改善之后:关于具体的改善过程和方式我写在了实验总结中
(5)继继续改善之后:
五、实验总结分析
1、在运行程序的过程中,我发现当我在命令行想要输出一些中文的时候,出现了乱码如下:
这是因为在命令提示符窗口中运行Java程序时,默认编码是GBK,但是在写代码是Java的编码方式和中文的编码方式都是Unicode,因此编码和解码的对照表标准不同,因此在命令行输出中文或者中文注释会出现乱码。
我把编码方式从默认的UTF-8编码转换成了ANSI编码然后再编写代码就不会出现这个错误了。
2、在第二个实验中,需要输出字符串,我使用了Scanner类,引用java.util.Scanner,但是不知为何一直出现以下问题:
找了很多方法都没有解决,之后发现是我写错了,应该是
我把System.in写成了Scanner.in,说明有时候问题可能不大,但却会对我们造成很大的影响,在写代码的时候出现问题,首先应该仔细检查自己并不熟悉的用法来提高效率。
3、判断字符串是否是“XYZ”,如果是就抛出异常,应该用方法equals()
并且当返回字符串类型时,方法也该定义为字符串类型: String str1; Public String isXYZ();
4、在声明一个将来用于表示具体数值的变量时,应该同时将它初始化为相对应数据类型规定的0值
对于以上错误,应该更改为:
5、关于第三个实验的改善:
(1)输出数据精确度的改变,double类型的变量score(Java实验成绩),因为不必要的精度不方便我对实验数据的观察,因此我对数据精度进行了一些限制:
限制之前:
限制之后:
(2)加上前面实验中对生日日期合法性的判断。
还有之前我对两种不同方法是分别声明了两个类,但后来发现这两个类中重复的部分太多,并且我主要将方法放在了main()方法中来实现,因此我将原本的两个类:Average1和Average2合并为了一个Average1类,用swith循环代替两种方法:
按1进入第一种方法,按2进入第二种方法,按其他数据退出: