我是一名c ++开发人员,我对java中的已检查和未经检查的异常非常新。 c ++中的异常规范根本就不好,这就是为什么没有人使用它。我喜欢检查过的异常,我有一个问题,让我们有这个界面:
public interface Warehouse {
MyStuff fetch(int id);
}
仓库可以以不同的方式实现:文件,数据库或内存(用于测试的模拟对象)。
现在,如果我想使用文件实现,我不能尝试在方法中打开文件,否则我的签名将会改变,我的类将不再实现该接口。此外,如果我有另一个具有另一个已检查异常的类,则所有其他现有实现都将受到影响。
我可以看到两种解决方案:
捕获已检查的异常并抛出另一个自定义运行时异常。我不认为这是一个很好的解决方案,为什么用户应该捕获运行时异常,说明在已经有标准和检查方法的情况下文件丢失。
在实现类的构造函数中执行整个作业,并使fetch函数无法抛出。我喜欢这种方式,对象既存在又有效,或者不存在。这种方法的唯一缺点是我们无法实现惰性评估;我们需要在构造函数中读取和解析文件,即使没有人会使用该对象。这效率不高。
我错过了什么吗?有没有更好的方法来避免这个问题?
答案 0 :(得分:2)
你的第一个解决方案是正确的。将您的界面更改为:
public interface Warehouse {
MyStuff fetch(int id) throws FetchFailureException;
}
并使每个子类将其IO,JDBC或任何异常包装在FetchFailureException中。如果不可恢复,则此FetchFailureException异常应为运行时,并检查是否可恢复。
答案 1 :(得分:0)
就个人而言,我会让Warehouse列出它可以抛出的所有异常(包括javadoc中未经检查的异常)
如果您有未列出的异常,则需要处理或包装它。 (无论是否检查)
您是否希望Warehouse是否要抛出已检查的异常。你不可能两种方式。 (实际上你可以,但它不是一个好主意,因为你可以在没有编译器知道的情况下盲目地抛出一个检查过的异常)
答案 2 :(得分:0)
最佳做法是指定方法将在界面中抛出的异常。
假设您有一个自定义的Exception类:
class MyException扩展Exception
{公共MyException (字符串消息)
{super(message);
公众 MyException(String message,Exception cause)
{
super(message,message, 原因);
}
}
处理MyException类中的所有异常,
现在,您可以在接口
中指定方法应该抛出的异常公共接口仓库
{
public MyStuff fetch()抛出MyException;
}
答案 3 :(得分:0)
我建议你在Warehouse
类中包含所有异常,然后使用子接口来处理非检查异常,如下所示:
public interface Warehouse {
MyStuff fetch(int id) throws FileNotFoundException;;
}
public interface FileWarehouse extends Warehouse {
@Override
MyStuff fetch(int id) throws FileNotFoundException;
}
public interface OtherWarehouse extends Warehouse {
@Override
MyStuff fetch(int id);
}