在这里首先想说的是:想做程序员就得多撸代码!!!不撸不知道,总是看着感觉很简单,实际动手写的时候各种想不到的问题出现了!然后痛苦的debug这个小来练习debug的时间比写时候用的时间多。希望各位幕友以此为戒。
关于注释中出现的“//清除缓存区中残留的空白符 很重要”注释 ,这个是java中Scanner类nextInt之后用nextLine无法读取输入的问题。大家可以参考这个链接,看了就明白了:http://blog.csdn.net/wjy1090233191/article/details/42080029
代码思路:
观察教程里老师给的运行效果图 可以看出 只有两种异常:图书不存在异常和输入错误异常
所以自定义这两个异常类 然后根据输入的各种不同情况 判断该抛出哪种异常。
特别需要注意的是:自定义的异常并不能自动检测异常并捕获,只能用虚拟机自带的异常捕获机制来 捕获到异常,然后再选择抛出哪个自定义的异常;或者自己用判断语句判断 何时来抛出自定义的异常。 具体可参考我的代码体会 (注释应该还算详细,嘿嘿)
例如:
Scanner input = new Scanner(System.in);
try{
int num = input.nextInt();
}catch(InputMismatchException e){ //这里可以捕获到异常
语句;
}
//但是 如下所示 自定义的异常并不能捕获到该类异常
Scanner input = new Scanner(System.in);
try{
int num = input.nextInt();
}catch(自定义异常类 e){ //这里是不能捕获异常的,实际运行可发现,实际差生的异常还是InputMismatchException
语句;
}
1,自定义两个异常类 用于在测试时抛出该异常
图书不存在 异常类
package ExceptionTest;
//自定义异常类
public class BookException extends Exception {
public BookException(String msg){
super(msg);
}
}
输入错误异常类
package ExceptionTest;
//自定义异常类
public class InputException extends Exception {
public InputException(String msg){
super(msg);//调用父类 的构造器方法
}
}
2,测试类Test main方法
package ExceptionTest;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
private static boolean flag = true;//while循环标志位
static Scanner input = new Scanner(System.in);//全局对象 input 静态修饰
static String[] books = {"第一行代码","数据结构与算法分析","剑指offer"};
static Test test = new Test();
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("欢迎使用本借书系统!");
test.tip();//用户提示信息
while(flag){
//try语句 检查异常
try {
int in = input.nextInt();
String s1 = input.nextLine();//清除缓存区中残留的空白符 很重要
String findBook = test.checkInput(in);//调用输入检查方法
System.out.println("您查找的是Book:"+findBook);
} catch (InputException e) {//用于捕获checkInput()方法中抛出的异常
// TODO Auto-generated catch block
System.out.println(e.getMessage());//打印异常信息
test.tip();
}
catch(BookException e){//用于捕获checkInput()方法中抛出的异常
System.out.println(e.getMessage());//打印异常信息
test.tip();
}
catch(InputMismatchException e){//这里只能用非自定义异常捕获了
System.out.println("命令输入错误!请根据提示输入数字命令!");
test.tip();
String s1 = input.nextLine();//清除缓存区中残留的空白符或第一次输入的非int型值 否则会死循环
/**进入该catch的情况分两种:
* 1.首次输入值是非int
* 如果第一就输入非int值的话,那么while循环里会一直进入该catch 所以陷入死循环
* 所以要清掉,
* 2.第一次输入2 选择按序号查找图书时,那么下面要求输入图书序号时,若输入非int
* 则在 checkInput()方法里case 2 中会检测异常 如果检测到异常 则再次调用checkBookId()方法
* 此时若再次输入非int 则在此catch中捕获
*
*/
}
}
}
//检查书名序号方法 具有可抛性
public String checkBookId() throws BookException{
System.out.println("请输入图书序号:");
int bookid = input.nextInt()-1;//这里若出现异常,则由InputMismatchException异常类进行捕获
//String s1 = input.nextLine();//清除缓存区中残留的空白符 很重要
//System.out.println(s1);
for (int i =0;i<books.length;i++){
if (i==bookid){
flag = false;//书已找到,结束 while 循环
return books[i];
}
}
throw new BookException("图书不存在!");//没找到就抛异常
}
//定义输入检查方法,并声明 可抛性 可多抛
public String checkInput(int newIn) throws InputException,BookException{
switch (newIn) {
case 1:
System.out.println("请输入图书名称:");
//此处不需要再try了,因为不论输入什么,都以String类型来存储
String bookName = input.nextLine();
for (String book : books){
if (bookName.equals(book)) {
flag = false;//书已找到,结束 while 循环
return book;
}
//注意,如果有return 语句的话 就不需要加 break 语句了 因为总会执行到return语句 或 throw
}
throw new BookException("图书不存在!");//抛异常
case 2:
try{
return test.checkBookId();
}catch(InputMismatchException e){
/**
* 这里只能用非自定义异常捕获了,不能用自定义异常捕获,自定义的异常不能自动捕捉此类异常,
* 自定义的异常只能用判断语句判断是否需要抛出
*/
System.out.println("命令输入错误!请根据提示输入数字命令!");
String s3 = input.nextLine();//清除缓存区中残留的空白符 很重要
return test.checkBookId();
/**
* 再次调用checBookId()方法 这里如果用户再次输入 非int型值 那么将再次会产生异常
* 并由while循环里的catch(InputMismatchException e){} 进行捕获(第2种情况)
* 然后 这时只能重新进入循环 重新选择查找方式了
*/
}
default:
throw new InputException("命令输入错误!请根据提示输入数字命令!");//抛输入错误异常
}
}
//提示信息方法
public void tip(){
System.out.println("请输入命令:1-按照书名查找图书;2-按照序号查找图书");
}
}
3,运行结果 图3 中出现的现象 已在代码中做了详细注释 这里也没有做进一步的深入处理,欢迎大家一起讨论,共同学习!
点击查看更多内容
12人点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦