如何返回一个对象列表并携带异常信息

4

我的Java程序有一个返回List的方法。它使用各种SQL查询填充列表。在某些情况下,数据可能不存在。在这种情况下我必须抛出一个异常。由于它是一个列表,列表可能包含有效数据。是否可以获取列表并捕获异常?


public List<Student> getStudentInfo(){
    //Contains some static info like name, dob of a Student
    List<Student> students = getStudentStaticInfo();
    try{
        for (Student student: students){
            student.setTotalMarks(getStudentMark(student.getId()));
            ...
        }
    catch(FailedToFetchDataException e) {
        throw new Exception("Failed to fetch data");
    } finally {
        return students;
    }

}

在这种情况下,该方法返回有效学生信息的列表。但是在发生异常的情况下,我无法找到问题所在。
是否有一种方式可以同时处理获取有效信息和获取异常情况?

1
当你得到异常时,显然列表是空的,那么你怎么能期望列表的结果呢? - Shriram
2
你应该创建一个包含数据和错误消息列表的对象。 - Jens
2
你可以创建一个包含列表的自定义异常。话虽如此,这似乎是一个非常奇怪的要求。你应该重新考虑你的逻辑,允许该方法返回一个值或抛出一个异常。 - Keppil
5个回答

6

只要发生异常,你的方法就会停止运行。否则,你将不得不处理多个异常。你可以这样做。

public List<Student> getStudentInfo(
                     BiConsumer<FailedToFetchDataException, Student> handleError) {
    //Contains some static info like name, dob of a Student
    List<Student> students = getStudentStaticInfo();
    for (Student student: students) {
        try{
            student.setTotalMarks(getStudentMark(student.getId()));
            ...
        } catch(FailedToFetchDataException e) {
            handleError.accept(e, student);
        }
    }
    return students;
}

3
你可以让调用者传入一个List对象:
public void getStudentInfo(List<Student> list){
    ...
}

在这个方法中,您可以使用结果填充列表,并在最后如果出现错误则抛出异常。

因此,调用者会收到错误通知,但仍然可以获得有效的数据返回。


1
你可以创建一个自定义异常,覆盖 FailedToFetchDataException 并附加私有字段,例如 StudentList<Student>

你可以像这样做:

CustomException e = new CustomException(msg);
e.setStudents(list);
throw e;

1
不要这样做。这是非常糟糕的实践。 - Philipp Sander
1
你能解释一下为什么这是一个不好的做法吗? - Advicer
4
异常用于处理异常情况,而不是返回值。不要仅仅因为可能而去做某事。 - Philipp Sander

1

一种方法是创建自己的异常,例如:

public class MyException extends Exception {

   private List<Student> list;

   public myException(List<Student> list) {
      this.list = list;
   }

   public List<Student> getList() {
      return list;
   }

   public void setList(List<Student> list) {
      this.list = list;
   }

}

当你捕获FailedToFetchDataException时,使用这个而不是Exception来抛出它。
然而,当你捕获FailedToFetchDataException时,最好只返回列表。

0
如果在异常情况下仍然可以使用数据,则可以将列表传递给方法,并将数据插入其中。例如:
public List<Student> getStudentInfo(List<Student> studentResults){
//Contains some static info like name, dob of a Student
List<Student> students = getStudentStaticInfo();
try{
    for (Student student: students){
        student.setTotalMarks(getStudentMark(student.getId()));
        studentResults.add(student);
        ...
    }
catch(FailedToFetchDataException e) {
    throw new Exception("Failed to fetch data");
} finally {
    return students;
}
}

现在studentResults将会被填充为以下之一:

  • 如果没有异常发生,所有学生记录将被填充
  • 在异常发生之前处理的学生记录。

如果您想要获取所有学生记录,无论setTotalMarks是否抛出异常,您可以在调用站点替代地调用getStudentStaticInfo


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接