2

在测试类的过程中,我发现我的类构造函数可以采用“非法参数”。构造函数需要一个 URI。显然,如果没有任何迹象表明传递的参数是一个 URI,那么它会抛出一个IllegalArgumentException.

我的构造函数最初测试了传递的参数以查看它是否是有效的 URI(通过从中创建文件)。然后我对其进行了修改以尝试创建文件并捕获IllegalArgumentException. 在我的catch块的主体中​​,我只是这样做:

throw new URISyntaxException(passedArgument, message)

这是捕获可能引发的异常的有效方法,还是我应该以其他方式进行?

另外,当我在测试时发现这个问题时,我是否有理由简单地修改代码以引发我期望的异常(这是一个更明显的错误呈现给用户,并放入日志中)?

编辑1:针对评论,这是我的代码示例:

public myClass (String fileName) throws URISyntaxException {
    try {
        fileToRead = new File(fileName);

        if ( !fileToRead.canRead() ) { //confirm we can read the passed file
            // if not, throw a URI error
            throw new URISyntaxException(fileName, 'bad filename passed, please check path and try again');
        }
    } catch ( IllegalArgumentException e ) {
        throw new URISyntaxException(fileName, 'bad filename passed, please check path and try again');
    }
}

catch本质上我的问题是,在 ? 的块内抛出 URI 异常是否有效IllegalArgumentException?这是一种有效的做法,还是我可以做得更好?

4

2 回答 2

5

是的,它既有效又是最佳实践,但您应该抛出自定义异常或 IllegalArgumentException 说明构造函数参数错误,而不是 UriException

于 2012-12-30T18:07:12.250 回答
4

您所做的并不是真正的异常链接,除非您实际上将捕获的异常包装在您抛出的异常中。相反,您只是通过尝试一个您知道如果违反先决条件将引发特定异常的操作来检测违反先决条件,然后通过引发另一个异常来报告违规。

我看到的唯一潜在问题是您是否真的确定您正在尝试的操作只会抛出您在特定情况下捕获的异常。如果可能有多个原因导致此操作抛出IllegalArgumentException.无效,只是因为其他一些论点无效)。

基本上,每当您捕获一个通用异常并抛出一个更具体的异常时,您可能会误认为通用异常的原因。但是如果你确定不存在这样的风险——例如,如果你调用的代码清楚地记录了它在什么条件下可能抛出的异常——那么它应该没问题。


将实际代码添加到问题后进行编辑:

大部分与上面讨论的一般原则无关,我看到你的代码有几个具体问题。

  1. First, if the File class your code uses is indeed java.io.File, and you're passing the filename to the constructor as a String rather than as a URI object, then the constructor you're calling isn't documented to throw an IllegalArgumentException in any case, so trying to catch one is pointless. The only File constructor that throws those is this one.

  2. Second, the fact that File.canRead() returns false doesn't necessarily mean that the filename is invalid — it might be perfectly valid, and the file might even exist, but your program might not have the necessary permissions to read it.

  3. 最后,正如其他人指出的那样,我不确定URIException您实际上抛出的 " " 是什么,除非它是您编写的自定义类(有一个javax.print.URIException,但那是一个接口,而不是一个类;唯一的另一个我可以从 Apache HTTP 客户端找到一个),但至少该名称似乎完全不适合您用来报告无效(或不可读)文件名的异常。你真的应该为此使用其他一些例外。

于 2012-12-30T18:20:05.693 回答