开发者社区> 问答> 正文

java异常捕获问题

 ArrayList<Integer> al = new ArrayList<>();
        Scanner scanner = new Scanner(System.in);
        //死循环 直到输入0结束
        while (true) {
            try {
                System.out.println("请输入一个数 输入0表示结束");           
                //如果在此输入一个非int类型的数据  则陷入一个死循环  为何不能重新给i赋值
                int  i = scanner.nextInt();
                if (i != 0) {
                    al.add(i);
                } else
                    break;
            } catch (Exception e) {
                // 捕获非int类型的异常
                System.out.println("错误 请输入整数");
            }
        }

展开
收起
蛮大人123 2016-06-01 16:46:01 2107 0
1 条回答
写回答
取消 提交回答
  • 我说我不帅他们就打我,还说我虚伪

    通过DEBUG追踪了下。
    Scanner最后是调用 public String next(Pattern pattern) 方法获取一个String对象,通过Pattern表示要获取对象的类型。
    代码如下

       public String next(Pattern pattern) {
            ensureOpen();
            if (pattern == null)
                throw new NullPointerException();
    
            // Did we already find this pattern?
            if (hasNextPattern == pattern)
                return getCachedResult();
            clearCaches();
    
            // Search for the pattern
            while (true) {
                String token = getCompleteTokenInBuffer(pattern);//尝试获取符合类型的结果
                if (token != null) { 
                    matchValid = true;
                    skipped = false;
                    return token;
                }
                if (needInput) //是否需要input数据
                    readInput();
                else
                    throwFor();
            }
        }

    问题就出在
    getCompleteTokenInBuffer(pattern)

    `if (needInput)
    readInput();`
    首先初次尝试失败后,会判断是否需要input数据,此时你还没有输入数据,因此通过readInput();得到数据的数据,并把needInput设置为了false
    然后再次调用
    getCompleteTokenInBuffer(pattern);
    然而调试里面的代码发现,当pattern指定的类型与你实际输入的类型不匹配时,并不会讲needInput设置为false,
    查看该方法的说明:

     /*
         * Returns a "complete token" that matches the specified pattern
         *
         * A token is complete if surrounded by delims; a partial token
         * is prefixed by delims but not postfixed by them
         *
         * The position is advanced to the end of that complete token
         *
         * Pattern == null means accept any token at all
         *
         * Triple return:
         * 1. valid string means it was found
         * 2. null with needInput=false means we won't ever find it
         * 3. null with needInput=true means try again after readInput (意味着这是readInput后的又一次尝试)
         */
        private String getCompleteTokenInBuffer(Pattern pattern) {
                /*
                    ...
                */
            }

    因此,当你循环调用next()方法时,只会不停的尝试将你上次输入的数据中获取你想要的int类型数据。

    2019-07-17 19:23:31
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载