我认为IOException和FileNotFoundException恰好是这种类型的异常。
不,它们实际上是“其他”类型的异常,超出了您的编程技能。无论您的编程水平有多好,编译器和库都会使您“意识到”可能会发生某些事情。
想象一下这种情况:
您创建了一个将数据保存到临时文件夹的应用程序。
一切都很顺利,您已经检查了文件夹是否存在,如果不存在,就自己创建它。
然后,您向该临时文件夹写入2 mb。
突然间,其他系统进程删除了您的临时文件夹,您无法再进行写入。
在代码中强制您检查此类异常,平台设计人员认为至少您知道了这一点。
Jon是正确的有时候你无能为力,可能在程序崩溃之前记录日志,这被认为是“处理异常”(处理不好,但至少处理了)
try {
....
} catch( IOException ioe ) {
logger.severe(
String.format("Got ioe while writting file %s. Data was acquired using id = %d, the message is: %s",
fileName,
idWhereDataCame,
ioe.getMessage()) );
throw ioe;
}
另一件事情是将异常"链接"起来以适应抽象层次。
可能你的应用程序有一个GUI界面,向用户显示IOException不会有任何意义,或者可能会导致安全漏洞。可以发送修改后的消息。
try {
....
} catch( IOException ioe ) {
throw new EndUserException("The operation you've requeste could not be completed, please contact your administrator" , ioe );
}
EndUserException 可能会在 GUI 的某个地方被捕获,并以对话框消息的形式呈现给用户(而不是只是在他的眼中消失而没有更多信息)。当然,您无法恢复该 IOException,但至少您可以死得有风度:P
最后,客户端代码可以使用不同的实现,并且并非所有异常都有意义。
例如,请再次考虑第一个场景。同一“操作”可能有三种“插件”服务来执行数据保存。
a) Write the data to a file.
b) Or, write to a db
c) Or write to a remote server.
接口不应抛出异常:
java.io.IOException
java.sql.SQLException
nor
java.net.UnknownHostException
但是实际上应该像这样:
my.application.DataNotSavedException
不同的实现将在正确的级别处理异常,并将其转换为适当的抽象:
客户端代码:
DataSaver saver = DataServer.getSaverFor("someKeyIdString");
try {
saver.save( myData );
} catch( DataNotSavedException dnse ) {
ShowEndUserError("Data could not be saved due to : " dnse.getMessage() );
}
实现代码:
class ServerSaver implements DataSaver {
....
public void save( Data data ) throws DataNotSavedException {
try {
Socket socket = new Socket( this.remoteServer, this.remotePort );
OuputStream out = socket.getOut....
....
....
} catch ( UnknownHostException uhe ) {
throw new DataNotSavedException( uhe );
}
}
}
FileSaver和DatabaseSaver会执行类似的操作。
所有这些都是Checked Exceptions,因为编译器让您检查它们。
何时使用其中之一(checked / unchecked):在这里
还有另外两种:在这里
最后,Runtime的更简单解释是:在这里