我创建了以下类:
-
抽象 Logger 类
-
实现实际 Logger 的抽象 Logger 类的三个子类
-
用作 Logger 接口的类
这三个子类可以抛出异常(创建文件,写入文件等) .
我应该直接在三个子类中捕获异常,还是重新抛出它并在接口中捕获它?或者可能在使用 Logger 接口的类中捕获?
其次,我有一个解析设置文件的类 . 我使用单例模式(在运行时只有一个实例) . 当然,在这个类中可能会发生异常(NullPointerException和IOException) .
我应该直接在这个类中捕获这些异常,还是将它重新抛给该类的客户端?
我的一般问题是,我不知道什么时候必须 grab 异常以及何时重新抛出异常 .
3 回答
部分Liskov substitution principle州:
当在客户端代码中将一种类型替换为另一种类型时,任何异常处理代码仍应起作用 .
如果您选择使用checked exceptions,Java会为您强制执行此操作 . (这不是建议使用已检查的异常,但我将在此处用来演示原理) .
这并不是说你应该捕获所有异常并进行转换 . 异常可能是意外的(即在已检查的异常环境中为
RuntimeExceptions
),您应该只转换匹配的异常 .例:
用法:
这是一个很好的实现,捕获一个异常,捕获和转换是有意义的,并传播其余的 .
这是翻译所有异常的错误代码,不需要满足Liskov:
当您知道如何处理该异常时,您应该捕获异常 .
这表明你应该对方法的异常
throws
,因为你不知道在那个阶段如何处理异常 .在我看来,异常应该总是传播回调用者 . 您可以随时捕获,记录然后从类本身重新抛出相同或自定义的异常,但最终应该由调用者处理 .
例如,如果
DataAccessException
出现在您的DAO类中,那么您可以在DAO中捕获并记录它,然后重新抛出一个传播到调用者类的自定义异常,然后调用者应该决定它需要对该异常做什么 .