JAVA实验三 异常处理程序设计

一、实验目的

了解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进入第二种方法,按其他数据退出:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/gui_bjyxszd/article/details/127812964