【问题标题】: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】:
您的fs 在try 块下声明...要解决此问题,请在块外声明:-
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】:
让我们从列出代码中的问题开始:
return 语句的编译错误是由于fs 超出其他答案中所述的范围。
当您对getFileScanner() 进行递归调用时,您不会分配或返回结果。所以它不会返回给调用者。
在finally 块中使用return 是一个坏主意。它将挤压(丢弃)任何其他可能在那时传播的异常;例如与catch 不匹配的异常或catch 块中引发的异常。
如果底层流到达 EOF,input.nextLine() 调用将抛出异常;例如用户键入 [CONTROL]+D 或其他。您不必必须捕获它(未选中),但finally 块中的返回会挤压它(可能)导致调用者得到null。呃……
硬连线System.in 和System.out 会降低您的方法的可重用性。 (好吧,在这种特殊情况下,这可能不是您应该解决的问题。我不会在下面...)
理论上,你的方法可以抛出一个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 方法主体,您可以确保该变量可以被方法主体中的所有块访问(try、catch 和 @ 987654328@ 块)。
希望有帮助!