【问题标题】:Try clause in While loop not executed after 1 loop在 1 个循环后未执行 While 循环中的 Try 子句
【发布时间】:2017-04-11 09:56:27
【问题描述】:

我的java类。它具有所有必要的软件包。我正在使用命令行界面。

public static boolean checkLibIDPass(){
    boolean continueLogin = true;
    boolean check = false;
    boolean retry = false;

    while (continueLogin){
        Scanner Sc = new Scanner(System.in);
        String _id,_pass;
        int goBack;

        System.out.println("Input Librarian ID: ");
        _id = Sc.next();
        System.out.println("Input Librarian Password: ");
        _pass = Sc.next();

        try {
            BufferedReader br = new BufferedReader(new FileReader("LibrarianFile.txt"));
            String line = null;

            while ((line = br.readLine()) != null && retry == false) {
                String[] values = line.split("\t",-1);

                for (int i=0; i < values.length; i++) {
                    if((_id.equals(values[0])) && (_pass.equals(values[1]))){
                        check = true;
                        retry = true;
                        System.out.println("Login Successful!");
                        break;
                    }
                    else if(i == values.length -1){
                        System.out.println("Librarian ID or Password is invalid");
                        System.out.println("Retry Login?" + "\n" + "1 : Yes"+ "\n" + "2 : Choose another user");
                        goBack = Sc.nextInt();
                        if (goBack == 1){
                            retry = true;
                            continueLogin = true;
                            break;
                        }
                        else if (goBack == 2){
                            retry = true;
                            continueLogin = false;
                            break;
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

    }
    return check;
}

我的输出:

Welcome to Knowledgica's Library Management System !
Which type of user are you?
1 : Guest
2 : Librarian
3 : Admin
4 : Exit
2
Input Librarian ID: 
aasdasd
Input Librarian Password: 
asdasdasd
Librarian ID or Password is invalid
Retry Login?
1 : Yes
2 : Choose another user
1
Input Librarian ID: 
asdasd
Input Librarian Password: 
asdasd
Input Librarian ID: 
sdasd
Input Librarian Password: 
asdasdas
Input Librarian ID: 

如果我想重试输入另一个 ID 和密码,我的目标是再次访问 try 子句。但是,它总是在没有 try 子句的情况下循环。

【问题讨论】:

  • 你关闭过BufferedReader吗?我不这么认为。要么在循环内关闭它,要么将该行从循环中取出,以便您打开文件一次,然后在循环内重新使用阅读器。然后在循环后关闭它。看看有没有帮助。
  • 我假设您的意思是如果登录无效,您要重新读取文件。好吧,您的代码不会发生这种情况,因为 while 循环在 try 内,而读取的文件在 while 之外。您可以有一个“已验证”布尔值并在一段时间内包装读取的文件(bool = false),然后如果凭据有效,则在当前循环中将 bool 设置为 true

标签: java while-loop try-catch


【解决方案1】:

domsson's answer大大提高了代码的可读性,但是要回答问题标题中隐含的问题:(Why is the) "Try clause in While loop not executed after 1 loop"?

实际上,try 子句又被执行了一次,但这并不明显,因为内部的 while 循环不再执行。这是因为您在每种情况下都将 retry 设置为 true,而内部 while 循环的条件是 retry == false

【讨论】:

  • 啊,难怪我应该将 retry == false 放在外部 while 循环中,这样它每次都会重置。
【解决方案2】:

评论变成了答案。不确定这是否真的解决了您的问题,我没有运行代码。
可能还有其他问题。但是,无论如何都应该修复下面列出的问题。


您的代码,大大简化:

public static boolean checkLibIDPass(){
    boolean continueLogin = true;
    boolean check = false;

    while (continueLogin) {
        Scanner Sc = new Scanner(System.in);
        String _id,_pass;

        System.out.println("Input Librarian ID: ");
        _id = Sc.next();
        System.out.println("Input Librarian Password: ");
        _pass = Sc.next();

        try {
            BufferedReader br = new BufferedReader(new FileReader("LibrarianFile.txt"));
            /* Do lots of stuff */
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    return check;
}

请注意,您在循环中打开了BufferedReader。如果您第二次进入循环,您将尝试再次打开它 - 在同一个文件上!除非您之前关闭阅读器,否则这不是一个好主意。您应该执行以下操作之一:

  1. 在循环结束时关闭阅读器
  2. 通过在循环外打开阅读器来重复使用阅读器

我推荐第二种方法,因为它应该表现更好。现在我们已经完成了,您也可以将Scanner 退出循环:

public static boolean checkLibIDPass(){
    boolean continueLogin = true;
    boolean check = false;

    Scanner sc = new Scanner(System.in); // create once
    String _id,_pass;

    BufferedReader br;

    try {
        BufferedReader br = new BufferedReader(new FileReader("LibrarianFile.txt")); // create once
        br.mark(); // remember this position (beginning)
    }
    catch (Exception ex) {
        ex.printStackTrace();
    }

    while (continueLogin) {
        System.out.println("Input Librarian ID: ");
        _id = sc.next();
        System.out.println("Input Librarian Password: ");
        _pass = sc.next();

        br.reset(); // go back to the beginning
        /* Do lots of stuff */
    }
    br.close(); // release the file
    sc.close(); // also best to close the scanner
    return check;
}

附加说明:考虑进一步拆分您的方法,这样您最终会得到简短且易于阅读的方法,其中每个方法都有非常有限且明确定义的职责。它也应该更容易找到代码中的错误。

【讨论】:

  • 我发现很难拆分这段代码,因为它主要是在其中循环,并且非常特定于手头的任务。顺便说一句,BufferedReader br 必须在外部 while 循环中,因为我在其中使用 br.readLine() 。搜索错误时忘记回写br.close 谢谢提醒。
  • Raika,您如何在程序的最开始阅读文本文件,将其保存到HashMap 或其他适当的集合中。这将使 id 和密码的查找更容易,并删除checkLibIDPass() 中的循环。那么,如何拆分方法,例如一种方法获取用户输入,另一种方法检查输入是否有效?然后可以将业务逻辑简化为几行,根据需要经常调用这两种方法。
  • 好的,我试试
猜你喜欢
  • 2015-04-24
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-13
  • 2014-09-10
相关资源
最近更新 更多