从概念上讲,我一直在决定我的项目的异常处理结构.
假设你有一个例子:
public abstract class Data {
public abstract String read();
}
Run Code Online (Sandbox Code Playgroud)
还有两个子类FileData,它从一些指定的文件读取你的数据,而StaticData,它只返回一些预定义的常量数据.
现在,在读取文件时,可能会在FileData中抛出IOException,但StaticData将永远不会抛出.大多数样式指南建议将Exception传播到调用堆栈,直到有足够的上下文可用于有效处理它.
但我真的不想在抽象的read()方法中添加throws子句.为什么?因为Data和使用它的复杂机器对文件一无所知,所以它只知道数据.此外,可能还有其他数据子类(以及更多这些子类)从不抛出异常并完美地传递数据.
另一方面,IOException是必要的,因为如果磁盘不可读(或某些此类),则必须抛出错误.所以我看到的唯一出路就是捕获IOException并在其位置抛出一些RuntimeException.
这是正确的哲学吗?
Osc*_*Ryz 26
你是对的.
异常应该在使用的相同抽象级别.这就是为什么java 1.4 Throwable支持异常链接的原因.没有必要为使用数据库的服务或"存储"不可知的服务抛出FileNotFoundException.
它可能是这样的:
public abstract class Data {
public abstract String read() throws DataUnavailableException;
}
class DataFile extends Data {
public String read() throws DataUnavailableException {
if( !this.file.exits() ) {
throw new DataUnavailableException( "Cannot read from ", file );
}
try {
....
} catch( IOException ioe ) {
throw new DataUnavailableException( ioe );
} finally {
...
}
}
class DataMemory extends Data {
public String read() {
// Everything is performed in memory. No exception expected.
}
}
class DataWebService extends Data {
public string read() throws DataUnavailableException {
// connect to some internet service
try {
...
} catch( UnknownHostException uhe ) {
throw new DataUnavailableException( uhe );
}
}
}
Run Code Online (Sandbox Code Playgroud)
请记住,如果您考虑继承编程,则应仔细设计特定方案并使用这些方案测试实现.显然,如果编写通用库代码更难,因为你不知道如何使用它.但大多数情况下应用程序都受限于特定域.
您的新例外应该是运行时还是已检查?这取决于,一般规则是抛出运行时编程错误并检查可恢复的条件.
如果通过正确编程可以避免异常(例如NullPointerException或IndexOutOfBounds),请使用Runtime
如果异常是由于某些外部资源不受程序员控制(例如网络停机)而且有一些事情可以做(可以在5分钟内显示重试消息),那么应该使用检查异常.
如果异常失控程序员,但可以完成NOTHING,则可以使用RuntimeException.例如,您应该写入文件,但文件已被删除,您无法重新创建它或重新尝试该程序应该失败(您无法做任何事情),最有可能是运行时.
请参阅Effective Java中的这两项:
我希望这有帮助.
如果你没有明确说明read()可以抛出异常,那么当它发生时你会给开发人员带来惊喜.
在您的特定情况下,我会捕获基础异常并将它们重新抛出为新的异常类DataException或DataReadException.
| 归档时间: |
|
| 查看次数: |
8379 次 |
| 最近记录: |