在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()抛出一个异常告诉你它不能读取那个文件。

这样,

  1. 调用者知道有问题,而不是得到一个不正确但有效的结果(即一个空列表)
  2. 调用者可以选择以需要的方式向用户发出错误信号(GUI 中的对话框、控制台应用程序中的消息、Web 应用程序中的 500 错误等)
  3. 调用者可以按照 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 列表,即使 IOExceptionScanner.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 并将异常处理留给调用者

如果您选择自己处理异常,请确保您没有让程序处于损坏状态,并且您清楚地告知调用者发生了什么。如果您不能或不愿意这样做,请将处理留给调用者。