在测试类时,我发现我的类构造函数可以采用“非法参数”。构造函数期待一个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
的{{1}}块中抛出URI异常是否有效?这是一种有效的做法,还是我能做得更好?
答案 0 :(得分:5)
是的,它既有效又是最佳实践,但您应该抛出自定义异常或IllegalArgumentException,说构造函数参数错误,而不是UriException
答案 1 :(得分:4)
你正在做的事情并不是exception chaining,除非你实际上把你抓到的那个异常包裹起来。相反,您只是通过尝试一个操作来检测违反前提条件,如果违反前提条件,您将知道该操作将抛出某个异常,然后通过抛出另一个异常来报告违规。
我看到的唯一潜在问题是你是否确实确定你正在尝试的操作只会抛出你在那种特定情况下捕获的异常。如果此操作可能抛出IllegalArgumentException
可能有多个原因,但您假设原因始终是特定原因,那么您报告该问题的异常可能最终会产生误导(例如,将有效的URI报告为无效,只是因为某些其他参数无效)。
基本上,每当你捕获一个通用异常并抛出一个更具体的异常时,就有可能会误认为泛型异常的原因。但是如果你确定没有存在这样的风险 - 例如,如果你所调用的代码清楚地记录了它在什么条件下可以抛出的异常 - 那么它应该没问题。
编辑:
与上面讨论的一般原则大多无关,我在您的代码中看到了几个具体问题。
首先,如果您的代码使用的File
类确实是java.io.File
,并且您将文件名作为String
传递给构造函数而不是URI
1}}对象,然后the constructor you're calling没有记录在任何情况下抛出IllegalArgumentException
,所以试图捕获一个是毫无意义的。投掷它们的唯一File
构造函数是this one。
其次,File.canRead()
返回false的事实并不一定意味着文件名无效 - 它可能完全有效,文件甚至可能存在,但您的程序可能没有必要阅读权限。
最后,正如其他人所指出的,我不确定你实际投掷的是什么“URIException
”,除非它是你写的自定义类(有一个{{ 3}},但这是一个接口,而不是一个类;我能找到的唯一另一个是来自Apache HTTP Client的javax.print.URIException
,但至少,这个名称似乎完全不适合你所遇到的异常用于报告无效(或不可读)的文件名。你真的应该使用其他一些例外。