【问题标题】:Building a Scanner with an embedded FileReader recursively in java在 java 中递归构建带有嵌入式 FileReader 的扫描仪
【发布时间】:2011-02-17 00:58:27
【问题描述】:
public static Scanner getFileScanner()
{
    try{
        Scanner input = new Scanner(System.in);
        String file = input.nextLine();
        Scanner fs = new Scanner(new FileReader(file));            
    }catch (FileNotFoundException fe) {
        System.out.println("Invalid filename. Try another:");
        getFileScanner();
    }finally{
        return fs;
    }
}

我不断收到找不到变量 fs 的错误消息。我一生都想不通为什么。

【问题讨论】:

    标签: java filereader java.util.scanner


    【解决方案1】:

    您的fstry 块下声明...要解决此问题,请在块外声明:-

    Scanner fs = null;
    try {
        ...
        fs = new Scanner(new FileReader(file));
    }
    catch (FileNotFoundException fe) {
        ...
    }
    finally {
        return fs;
    }
    

    【讨论】:

      【解决方案2】:

      try 块内声明的变量不在相应finally 块内的范围内。一般来说,您的方法存在许多问题...例如,在 finally 块内使用 return 通常不是一个好主意。

      这是我要做的:

      public static Scanner getFileScanner() {
        Scanner input = new Scanner(System.in);
        File file = null;
        while (true) {
          file = new File(input.nextLine());
          if (file.exists() && file.isFile())
            break;
          System.out.println("Invalid filename. Try another:");
        }
        return new Scanner(new FileReader(file));
      }
      

      【讨论】:

        【解决方案3】:

        让我们从列出代码中的问题开始:

        1. return 语句的编译错误是由于fs 超出其他答案中所述的范围。

        2. 当您对getFileScanner() 进行递归调用时,您不会分配或返回结果。所以它不会返回给调用者。

        3. finally 块中使用return 是一个坏主意。它将挤压(丢弃)任何其他可能在那时传播的异常;例如与catch 不匹配的异常或catch 块中引发的异常。

        4. 如果底层流到达 EOF,input.nextLine() 调用将抛出异常;例如用户键入 [CONTROL]+D 或其他。您不必必须捕获它(未选中),但finally 块中的返回会挤压它(可能)导致调用者得到null。呃……

        5. 硬连线System.inSystem.out 会降低您的方法的可重用性。 (好吧,在这种特殊情况下,这可能不是您应该解决的问题。我不会在下面...)

        6. 理论上,你的方法可以抛出一个StackOverflowError;例如如果用户多次点击 [ENTER]。这个问题是您的递归解决方案中固有的,并且是不这样做的一个很好的理由。

        最后,这是解决这些问题的方法的一个版本:

        public static Scanner getFileScanner() throws NoSuchElementException
        {
            Scanner input = new Scanner(System.in);
            while (true) {
                String file = input.nextLine();
                try {
                    return new Scanner(new FileReader(file));           
                } catch (FileNotFoundException fe) {
                    System.out.println("Invalid filename. Try another:");
                }
            }
        }
        

        请注意,我已经替换了递归,摆脱了finally,并声明了抛出的异常。 (可以捕获该异常并报告它,或者将其作为特定于应用程序的异常重新抛出。)

        【讨论】:

          【解决方案4】:

          您在 try 块中声明了 fs 并尝试在不同的范围(finally 块)中访问它。通常的范例是在 try 块之前将 fs 声明为 null。

          【讨论】:

            【解决方案5】:

            先声明:

            public static Scanner getFileScanner() {
                Scanner input = new Scanner(System.in);
                Scanner fs = null;
                while(fs == null) {
                    try{
                        String file = input.nextLine();
                        Scanner fs = new Scanner(new File(file));            
                    }catch (FileNotFoundException fe) {
                        System.out.println("Invalid filename. Try another:");
                    }
                }
                return fs;
            }
            

            【讨论】:

              【解决方案6】:

              只是为了扩展其他人用他们的代码示例表示的内容......

              因为您在try 块中声明了fs 变量,所以该变量将仅在try 关键字之后紧跟在大括号内的范围内(可见)。

              通过将 fs 变量声明移出 try 块并进入 getFileScanner 方法主体,您可以确保该变量可以被方法主体中的所有块访问(trycatch 和 @ 987654328@ 块)。

              希望有帮助!

              【讨论】:

                猜你喜欢
                • 2021-11-05
                • 1970-01-01
                • 2012-06-13
                • 1970-01-01
                • 2021-01-14
                • 2019-07-27
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多