在 java 中递归构建带有嵌入式 FileReader 的扫描仪
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 未找到的错误。我一生都无法弄清楚为什么。
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;
}
}
I keep getting the error that the variable fs isn't found. I can't figure out why for the life of me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您的
fs
是在try
块下声明的...要解决此问题,请在块之外声明它:-Your
fs
is declared undertry
block... to fix this, declare it outside the block:-在
try
块内声明的变量不在相应的finally
块内的范围内。一般来说,您的方法存在许多问题......例如,在finally
块内return
通常不是一个好主意。这就是我要做的:
Variables declared inside a
try
block are not in scope inside the correspondingfinally
block. There are a number of issues with your approach in general... it's generally not a good idea toreturn
inside afinally
block, for example.Here's what I'd do:
让我们首先列出代码中的问题:
return
语句上的编译错误是由fs
超出其他答案中所述的范围引起的。当您递归调用
getFileScanner()
时,您不会分配或返回结果。因此它不会返回给调用者。在
finally
块中使用return
是一个坏主意。它将压制(丢弃)此时可能传播的任何其他异常;例如,与catch
不匹配的异常或在catch
块中引发的异常。如果底层流已到达 EOF,则
input.nextLine()
调用将引发异常;例如,用户输入 [CONTROL]+D 或其他内容。您不必必须捕获它(它是未经检查的),但是finally
块中的返回会挤压它(可能)导致调用者得到null
相反。呃...硬连线
System.in
和System.out
使您的方法的可重用性降低。 (好吧,在这种特殊情况下,这可能不是您应该解决的问题。而且我不会,如下...)理论上,您的方法可以抛出
StackOverflowError
;例如,如果用户多次点击 [ENTER]。这个问题是你的递归解决方案所固有的,并且是不这样做的一个很好的理由。最后,这是解决这些问题的方法的一个版本:
请注意,我已经替换了递归,摆脱了
finally
,并声明了引发的异常。 (可以捕获该异常并报告它,或者将其作为应用程序特定的异常重新抛出。)Lets start by listing the problems in your code:
The compilation error on the
return
statement is caused byfs
being out of scope as described in other answers.When you make the recursive call to
getFileScanner()
, you don't assign or return the result. So it won't make it back to the caller.Using a
return
in afinally
block is a bad idea. It will squash (throw away) any other exceptions that might be propagating at that point; e.g. exceptions that don't match acatch
or exceptions thrown in acatch
block.The
input.nextLine()
call will throw an exception if the underlying stream has reached the EOF; e.g. the user typed [CONTROL]+D or whatever. You don't have to catch it (it is unchecked), but the return in thefinally
block squashes it (probably) resulting in the caller getting anull
instead. Ughh ...Hard-wiring
System.in
andSystem.out
makes your method less reusable. (OK, this may not be an issue you should address in this particular case. And I won't, below ...)In theory, your method could be made to throw a
StackOverflowError
; e.g. if the user hits [ENTER] a number of times. This problem is inherent in your recursive solution, and is a good reason not to do it that way.Finally, here's a version of the method that addresses these problems:
Note that I've replaced the recursion, gotten rid of the
finally
, and declared the exception that is thrown. (One could catch that exception and either report it, or rethrow it as an application specific exception.)您在 try 块中声明了 fs 并尝试在不同的范围(finally 块)中访问它。通常的范例是在 try 块之前将 fs 声明为 null。
You declared fs in the try block and try to access it in a different scope (the finally block). The usual paradigms is to declare fs before the try block as null.
先声明一下:
Declare it first:
只是为了扩展其他人在他们的代码示例中指出的内容...
因为您在
try
块中声明了fs
变量,所以该变量的作用域仅在以下范围内(可见)try
关键字后面的大括号。通过将
fs
变量声明移出 try 块并移入getFileScanner
方法主体,您可以确保该变量可以被方法主体内的所有块访问(>try
、catch
和finally
块)。希望有帮助!
Just to expand on what the other guys indicated with their code samples...
Because you declare the
fs
variable within thetry
block the variable will only be scoped (visible) within the braces immediately after thetry
keyword.By moving the
fs
variable declaration out of the try block and into thegetFileScanner
method body you are ensuring that the variable can be accessed by all blocks within the method body (try
,catch
andfinally
blocks).Hope that helps!