Java调试的重要,异常处理中输入异常处理问题

来源:互联网 发布:sql语句按月查询 编辑:程序博客网 时间:2024/06/08 08:14

上周五我们学习了Java异常处理的一些基本知识,周末就做了关于用try..catch修改我们以前做的一个模拟ATM取款机的练习。

    /**

     * 显示登陆界面

     */

    public void showLogin(){

       Scanner sc = new Scanner(System.in);

       System.out.print("请输入帐号:");

       int accountId = 0;

       try{

           accountId = sc.nextInt();

       }catch (InputMismatchException e){

           System.out.println("请按正确要求输入!");

           showLogin();

       }

       System.out.print("请输入密码:");

       int pwd = 0;

       try{

           pwd = sc.nextInt();

       }catch (InputMismatchException e){

           System.out.println("请按正确要求输入!");

           showLogin();

       }

       /**

        * 判断密码是否正确

        */

       if(account.vertify(accountId, pwd)){

           /**

            * 进入菜单界面

            */

           showControl();

       }

       else{

           /**

            * 递归调用自身

            */

           System.out.println("密码错误,请重新输入!");

           showLogin();

       }

    }

其中就遇到了一个问题,我们做的atmView类中的一个方法是要求用户输入账号密码的,其中pwdaccountId 我们定义为int类型,为了防止用户乱输入导致程序异常,我们在输入那儿加了try块。可是问题就来了,我们这个方法中如果判断用户账号密码不对就会递归调用自身,可是当他运行时,除了第一次会要求用户输入外,他不会在调用输入方法,导致程序出现死循环,直至堆溢出。

开始时我考虑是不是因为加了try…catch的原因导致的,毕竟以前没修改时都运行正常。所以考虑是因为程序抛出异常后,又递归调用所以抛出的异常未清空导致二次不进入try进行尝试运行就直接进入异常处理的原因。所以我就按这方面的思路上网查资料,可是一无所得。

后来还是在J2EE群组交流群的一位成员提醒我,叫我把调试结果发给他。我在调试的时候才发现,自己开始的思路是完全错误的。因为调试的时候程序是进入了try块的。只是在要求用户输入的accountId = sc.nextInt();这儿直接跳过了,看来问题是出在Scanner方法这儿。

我们先来看看关于Scanner的信息:

java.util.Scanner[delimiters=/p{javaWhitespace}+][position=3][match valid=true][need input=false][source closed=false][skipped=false][group separator=/,][decimal separator=/.][positive prefix=][negative prefix=/Q-/E][positive suffix=][negative suffix=][NaN string=/Q�/E][infinity string=/Q∞/E]

    我们知道当我们不按要求输入时,scanner会抛出一个InputMismatchException异常,其实我们比对scanner的信息不难发现,其中有一项match valid=true 就是这项标识是否输入匹配的。调试中我们发现这项一旦输入不匹配就会变为false,而第二次输入时就不会再要求输入了。

    因为我们在程序中输入十分常见,我们一般把private Scanner sc = new Scanner(System.in);定义为私有的方便所有方法调用。这样一旦我们输入异常后,sc中的match valid=true就会变为false了,第二次递归调用就不会再要求用户输入。

       所以解决的办法是在方法里定义一个Scanner sc = new Scanner(System.in);让方法每次被调用时都在初始化sc就能解决该问题了。

    通过今天遇到的这个问题,向我们再次展示了Java编程中调试的重要性!

    Ps: 这不是最佳解决办法,而且问题的描述有问题,请看下篇博客!