使用try-and-catch时经常遇到一些问题:
1)有些变量需要在try括号内声明,否则它们不在范围内 2)最终,即使我的返回语句最终必须在try括号中,但该方法不会返回任何内容。
解决此类问题的正确方法是什么。
导致此问题的方法示例如下所示。它需要处理一个FileNotFoundException并处理一个IOException。我如何最优雅地做到这一点?
public static String getContents (File file) {
BufferedReader reader = new BufferedReader(new FileReader(file));
String contents = new String();
while (reader.ready())
contents += reader.readLine();
return contents;
}
答案 0 :(得分:10)
如果在getContents
方法中不需要进行异常处理,还有一个选项 - 向方法添加throws
子句以使该方法抛出异常:
public static String getContents (File file)
throws IOException, FileNotFoundException {
这样,调用该方法的代码将处理Exception
而不是方法本身。如果try
被抛出到调用它的方法,则该方法中不需要catch
/ Exception
块。
这可能是也可能不是处理这种情况的理想方式,具体取决于预期方法的行为方式。
修改强>
第二个想法,让方法抛出异常可能是一个好主意。我认为D.Shawley的评论我认为总结得很好 - “异常处理应该意味着只处理有意义的异常。”
在这种情况下,getContents
方法似乎获取指定File
的内容,并向调用者返回String
。
如果要在getConents
方法中执行异常处理,则表明发生错误的唯一方法是将某种预定值(例如null
)返回到调用者通知错误发生。
但是,通过让方法本身向调用者返回异常,调用者可以选择做出相应的反应:
try {
String contents = getContents(new File("input.file"));
} catch (IOException ioe) {
// Perform exception handling for IOException.
} catch (FileNotFoundException fnfe) {
// Inform user that file was not found.
// Perhaps prompt the user for an alternate file name and try again?
}
不是让setContents
方法提出自己的协议来通知发生错误,而是将IOException
和FileNotFoundException
抛回方法调用者可能会更好,因此可以在可以进行适当替代操作的地方执行异常处理。
只有在可以进行某些有意义的处理时才应执行异常处理。
答案 1 :(得分:5)
您可以按照以下方式处理:
StringBuilder contents = new StringBuilder();
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(file));
while (reader.ready()) {
contents.append(reader.readLine());
}
} catch (FileNotFoundException fne) {
log.warn("File Not Found", fne);
} catch (IOException ioe) {
log.warn("IOException", ioe);
}
return contents.toString();
你可能应该在上面的情况下使用StringBuilder而不是String,但在性能方面要好得多。
答案 2 :(得分:3)
public static String getContents (File file) {
String contents = new String();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
while (reader.ready())
contents += reader.readLine();
}
catch (FileNotFoundException ex) {
// handle FileNotFoundException
}
catch (IOException ex) {
// handle IOException
}
finally {
if (reader != null) {
try {
reader.close();
}
catch (IOException ex) {
// handle IOException
}
}
}
return contents;
}
我添加了finally
块来关闭BufferedReader
,但您没有在代码中执行此操作。我还建议您使用StringBuilder
而不是String
连接,但有人已经指出了它。 reader
的声明和官方化仅在try
块之外,因为我添加了finally
块;否则,引用reader
可以在try
块内声明。
我没有处理例外,我认为这与你的问题无关。
答案 3 :(得分:1)
您可以尝试将return语句移动到finally
块中。
答案 4 :(得分:1)
关于变量范围,我不确定是否有更优雅的方法来做到这一点。通常我会尝试在出现错误时考虑返回值,然后将变量赋值给该值。
关于return语句,如果你使用我的上述建议,你可以在try / catch块之后返回。
因此,如果我使用空返回值来指示我将要执行的错误
public static String getContents (File file) {
String contents = null;
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
contents = new String();
while (reader.ready())
contents += reader.readLine();
} catch (Exception e) {
// Error Handling
}
return contents;
}
答案 5 :(得分:1)
这里缺少的是一个简单的实用程序,可以大大简化清理工作:
public static void closeAndLog(Closable c) {
if ( c == null )
return;
try {
c.close()
} catch ( IOException e) {
LOGGER.warn("Failed closing " + c +, e);
}
}
这样您的代码就可以成为:
public static String getContents (File file) throws IOException {
BufferedReader r = null;
try {
r = new BufferedReader(...);
// do stuff
} finally {
closeAndLog(r);
}
}
答案 6 :(得分:0)
恕我直言,你有两种方法可以正确处理异常(这里是IOException和FileNotFoundException):
要获得有关例外的好建议,另请参阅:Why do Java people frequently consume exceptions silently?
答案 7 :(得分:0)
从Java 7开始,您可以使用try-with-resources来确保资源正确关闭并自动“关闭”。您所需要的只是一个实现var curry = document.getElementsByClassName('active')[0];
$(window).load(function() {
curry.style.left = '0px';
});
java.lang.AutoCloseable
的对象。实际上文档中有以下示例:
BufferedReader