在java中应该如何更好地处理这个异常?
How should this exception be handled better in java?
所以我正在编写这段代码(见下文),我的老师说只做一个 System.out.println
是不好的做法,我应该做一些其他事情来更好地处理异常。但是怎么办?
public static List<Highscore> readHighScoreTable(String fileName) {
//creates a new ArrayList of highscores.
List<Highscore> result = new ArrayList<Highscore>();
try {
//creates a new bufferedReader that reads from the file.
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line = null;
//a loop that reads through all the lines in the file.
while((line = reader.readLine()) != null) {
//some code }
reader.close();
} catch(IOException ioe) {
//If there is a problem, it prints a error message.
System.out.println("There was a problem reading your file.");
}
return result;
}
非常感谢任何帮助。
当您打印一些静态字符串时,您以后无法理解异常发生的原因和位置
使用
ioe.printStackTrace();
The java.lang.Throwable.printStackTrace() method prints this throwable
and its backtrace to the standard error stream. It prints a stack
trace for this Throwable object on the error output stream that is the
value of the field System.err.
你根本不应该捕获异常。
该方法应将 IOException
添加到其 throws
子句中,以向调用者发出无法读取其提供的文件的信号。正如new FileReader()
抛出一个异常告诉你它不能读取那个文件。
这样,
- 调用者知道有问题,而不是得到一个不正确但有效的结果(即一个空列表)
- 调用者可以选择以需要的方式向用户发出错误信号(GUI 中的对话框、控制台应用程序中的消息、Web 应用程序中的 500 错误等)
- 调用者可以按照 wants/needs 的方式处理异常:尝试另一个文件,稍后重试,将错误记录在文件中,等等。
简而言之,如果你不能以正确的方式处理异常,因为这不是你的责任,你不应该捕获异常。或者至少,如果你抓住它,你应该抛出另一个,与原始异常链接。
这里方法的职责是读取并解析一个文件。它不是处理与用户的交互。因此它应该抛出异常,直到负责处理与用户交互的代码可以捕获它并显示错误。
事实上,您大致有两种处理异常的方法。
捕获它让执行继续或将它传播给调用者。
这里你选择了第一种方式:
catch(IOException ioe) {
//If there is a problem, it prints a error message.
System.out.println("There was a problem reading your file.");
}
但您只是在输出中写了一条文本消息。
那还不够。要获得有价值的信息,您需要包含异常和引发异常的语句的整个堆栈跟踪。
您可以将其写入错误标准:ioe.printStackTrace()
或使用记录器更好。
此处您选择了第一种方式(捕获异常),因为您想要 return 列表,即使 IOException
在 Scanner.readLine()
期间发生。
在某些情况下,它可能是可以接受的。
在其他情况下,要求可能不同,您不想从异常中恢复。所以你让它传播给调用者。
在这种情况下,列表当然不会 returned 添加任何元素。
这是一个将异常传播给调用者的版本。
请注意,在任何情况下都应关闭输入流。
因此,要么在 finally
语句中执行,要么更好,使用确保资源释放的 try-with-resources
语句。
public static List<Highscore> readHighScoreTable(String fileName) throws IOEexception {
//creates a new ArrayList of highscores.
List<Highscore> result = new ArrayList<Highscore>();
//creates a new bufferedReader that reads from the file.
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))){
String line = null;
//a loop that reads through all the lines in the file.
while((line = reader.readLine()) != null) {
//some code
}
}
return result;
}
和代码客户端:
try{
List<Highscore> highScores = readHighScoreTable("filename");
}
catch (IOException e){
// log the exception
// give a feeback to the user
}
您可以做几件不同的事情:
打印异常原因:System.out.println("There was a problem reading your file, error:" + ioe.getMessage());
打印整个堆栈跟踪(对开发人员有用,但对最终用户无用):ioe.printStackTrace();
return null
向调用者发出出错的信号(但您必须记录)
传播异常,然后标记您的方法抛出 IOException
并将异常处理留给调用者
如果您选择自己处理异常,请确保您没有让程序处于损坏状态,并且您清楚地告知调用者发生了什么。如果您不能或不愿意这样做,请将处理留给调用者。
所以我正在编写这段代码(见下文),我的老师说只做一个 System.out.println
是不好的做法,我应该做一些其他事情来更好地处理异常。但是怎么办?
public static List<Highscore> readHighScoreTable(String fileName) {
//creates a new ArrayList of highscores.
List<Highscore> result = new ArrayList<Highscore>();
try {
//creates a new bufferedReader that reads from the file.
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line = null;
//a loop that reads through all the lines in the file.
while((line = reader.readLine()) != null) {
//some code }
reader.close();
} catch(IOException ioe) {
//If there is a problem, it prints a error message.
System.out.println("There was a problem reading your file.");
}
return result;
}
非常感谢任何帮助。
当您打印一些静态字符串时,您以后无法理解异常发生的原因和位置
使用
ioe.printStackTrace();
The java.lang.Throwable.printStackTrace() method prints this throwable and its backtrace to the standard error stream. It prints a stack trace for this Throwable object on the error output stream that is the value of the field System.err.
你根本不应该捕获异常。
该方法应将 IOException
添加到其 throws
子句中,以向调用者发出无法读取其提供的文件的信号。正如new FileReader()
抛出一个异常告诉你它不能读取那个文件。
这样,
- 调用者知道有问题,而不是得到一个不正确但有效的结果(即一个空列表)
- 调用者可以选择以需要的方式向用户发出错误信号(GUI 中的对话框、控制台应用程序中的消息、Web 应用程序中的 500 错误等)
- 调用者可以按照 wants/needs 的方式处理异常:尝试另一个文件,稍后重试,将错误记录在文件中,等等。
简而言之,如果你不能以正确的方式处理异常,因为这不是你的责任,你不应该捕获异常。或者至少,如果你抓住它,你应该抛出另一个,与原始异常链接。
这里方法的职责是读取并解析一个文件。它不是处理与用户的交互。因此它应该抛出异常,直到负责处理与用户交互的代码可以捕获它并显示错误。
事实上,您大致有两种处理异常的方法。
捕获它让执行继续或将它传播给调用者。
这里你选择了第一种方式:
catch(IOException ioe) {
//If there is a problem, it prints a error message.
System.out.println("There was a problem reading your file.");
}
但您只是在输出中写了一条文本消息。
那还不够。要获得有价值的信息,您需要包含异常和引发异常的语句的整个堆栈跟踪。
您可以将其写入错误标准:ioe.printStackTrace()
或使用记录器更好。
此处您选择了第一种方式(捕获异常),因为您想要 return 列表,即使 IOException
在 Scanner.readLine()
期间发生。
在某些情况下,它可能是可以接受的。
在其他情况下,要求可能不同,您不想从异常中恢复。所以你让它传播给调用者。
在这种情况下,列表当然不会 returned 添加任何元素。
这是一个将异常传播给调用者的版本。
请注意,在任何情况下都应关闭输入流。
因此,要么在 finally
语句中执行,要么更好,使用确保资源释放的 try-with-resources
语句。
public static List<Highscore> readHighScoreTable(String fileName) throws IOEexception {
//creates a new ArrayList of highscores.
List<Highscore> result = new ArrayList<Highscore>();
//creates a new bufferedReader that reads from the file.
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))){
String line = null;
//a loop that reads through all the lines in the file.
while((line = reader.readLine()) != null) {
//some code
}
}
return result;
}
和代码客户端:
try{
List<Highscore> highScores = readHighScoreTable("filename");
}
catch (IOException e){
// log the exception
// give a feeback to the user
}
您可以做几件不同的事情:
打印异常原因:
System.out.println("There was a problem reading your file, error:" + ioe.getMessage());
打印整个堆栈跟踪(对开发人员有用,但对最终用户无用):
ioe.printStackTrace();
return
null
向调用者发出出错的信号(但您必须记录)传播异常,然后标记您的方法抛出
IOException
并将异常处理留给调用者
如果您选择自己处理异常,请确保您没有让程序处于损坏状态,并且您清楚地告知调用者发生了什么。如果您不能或不愿意这样做,请将处理留给调用者。