在哪里处理异常

8

我目前正在处理一个项目,遇到了一个有点难以理解的问题。我已经学习Java编程两年了,也学过异常处理,但从未真正理解过。

在我的当前情况下,我的主方法初始化了一个类。

WikiGraph wiki = wiki = new WikiGraph(getFile());

Wikigraph构造函数需要一个文件名,我通过getFile()方法从DialogBox中获取。
然后,Wikigraph的构造函数调用了一个名为loadfile(filename)的方法,该方法尝试加载和解析给定的文件。
loadfile()方法中,我会抛出一个IncorrectFileTypeError异常。
我的问题是,我应该在哪里处理这个异常?
目前,我在loadfile()方法中捕获它。
try {
    //load file
} catch (IncorrectFileTypeError e){
    System.out.println("Incorrect file type: "+filename+": "+e.getMessage());
    throw new IncorrectFileTypeError();
}

但我也可以在WikiGraph初始化时进行捕获,如下所示:
while(wiki==null){                          //While There is no valid file to add to the wikigraph
    try {
        wiki = new WikiGraph(getFile());    //Try to load file  
    } catch (IncorrectFileTypeError e) {    //If file cannot be loaded
        JOptionPane.showMessageDialog(null, "Incorrect File Type Given. Please Choose another file."); //Display error message
        getFile();                          //Prompt user for another file
    }
}

现在我处理错误的方式是正确/最好的方式吗?还是应该在getFile()方法中处理?

编辑:我想我应该让文件问题更清晰一些。 不正确的文件类型错误不是基于文件扩展名,因此它可能是一个误导性的错误名称。 给定的文件可以有任何扩展名,但其内容必须格式良好。


这是关于人们如何处理异常处理的主观看法。我会把它放在社区维基中。 - Ascalonian
6个回答

4
在这种情况下,我建议避免使用异常作为处理不正确文件类型的主要方法。如果用户输入经常会触发异常,那么它就不应该被视为异常。以下是我会采取的方法:
1. 通过标准控制流检查文件类型,并在文件类型无效时向用户发出警告。您可以考虑在WikiGraph上添加一个静态方法IsFileValid(filename)。
2. 在WikiGraph初始化期间,如果文件类型无效,则抛出异常。
这种方法使您既有机会在提供无效数据时向用户发出警告,又可以确保从WikiGraph的角度来看所提供的信息是准确的。它为针对WikiGraph工作的开发人员提供了一种确保其输入有效而不一定需要异常处理的方法。

啊,是的,但我的文件扩展名没有设置。我被给了一个样本.idx文件进行处理。它可以是.txt或任何其他格式,所以我不能基于文件名扩展名进行检查,只能基于文件内容进行检查。 isFileValid()方法将需要解析文件以检查其是否有效,因此既然loadfile()方法中已经发生了这种情况,我是否应该在那里捕获它。 - Chris Salij
是的,不幸的是这种问题可能会出现。如果文件可以进行相对简单的检查(例如检查头文件),我仍然建议在UI级别失败而不是抛出异常,但是对于更复杂的检查,您可能需要在loadfile()中进行检查。 - Ryan Brunner
1
@Chris:我不同意。如果文件无效,显然他试图创建的WikiGraph实例无法正确初始化。允许部分初始化的实例非常危险。所以我会让构造函数声明异常,然后在构造函数周围放置try-catch。当然,try仍然会提示用户。 - sleske
1
@sleske:实际上这是一个非常好的观点。我没有考虑过这个问题。所以我会在loadFile()方法中抛出错误,但我会在构造函数中捕获它,并在初始化时处理它? - Chris Salij
1
@Chris:是的,重要的一点是在构造函数之外捕获异常。这样(至少在Java中),您将不会得到一个未完全初始化的实例。 - sleske

3
异常处理的主要好处之一是它们为您提供了方便的手段来处理远离异常发生地点的异常。在不支持它的语言中,您必须对路径上的每个调用检查返回值,中断并返回,以便手动传播。
在您认为可以从中恢复或最好报告并取消操作的地方处理异常是有意义的。
我的理解是交互始于UI输入,如果文件类型不合适,则无法真正恢复。因此,我会让启动文件打开任务的任何UI任务捕获异常,向用户报告发生错误,并取消或请求不同的输入。
第二次阅读时,似乎您在尝试创建图表后才打开对话框。我个人喜欢隔离UI交互。因此,我个人首先处理所有UI输入,获取预期的文件名,验证它是否符合我的需求,如果不符合,则向用户报告,仅在文件正确时继续,然后仅报告关键和意外错误。

1

我认为在loadfile中捕获它没有意义。你仍然可以编写日志消息(使用System.err),只需在抛出异常之前执行即可。您正在正确的轨道上,可以在可以处理它的地方捕获异常(在这种情况下再次提示用户)。


1
对于“在你可以处理异常的地方捕获异常”,给予加1分,但对于“你仍然可以写日志信息”,给予减1分。请,请不要同时记录和抛出异常(参见例如http://codemonkeyism.com/7-good-rules-to-log-exceptions/,“不要记录并重新抛出”)。异常*将*在某个地方被处理,那里应该做出记录的决定。否则,您将为一个错误获得两个日志条目,这可能会极其混乱。 - sleske
我从未说过重新抛出异常。我说过在抛出异常之前记录日志。在这种情况下,我认为loadfile是唯一适合记录日志的级别。 - Matthew Flaschen

1
如果问题是用户选择了错误类型的文件,那么我认为您根本不应该让代码继续执行到那一步。这似乎并不像应该是一个异常,而更像是程序中的一条路径。如果用户选择了错误的文件类型,则应该给他重新选择文件的机会。显然,如果只需查看扩展名就可以轻松地限制 JFileChooser 中的选项为正确类型的文件。

1

我认为这是检查异常设计的情况(无论您是否同意)。我假设IncorrectFileTypeError扩展了Error?扩展RuntimeException更合适,扩展IOException更好,因为这种类型的错误可能会由有效的用户输入触发(即键入存在但类型错误的文件名)。


0

我相信这种类型的错误(IncorrectFileTypeError)可以通过在用户输入表单中解决,避免不必要的往返文件系统服务层。


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