我认为 IOException 和 FileNotFoundException 正是这种异常
不,这些实际上是“其他”类型的异常,超出了您的编程技能。无论你的程序有多好,编译器和库都会让你“意识到”某些事情可能会发生。
想想这个场景:
您创建一个将数据保存到临时文件夹的应用程序。
一切正常,您已检查该文件夹是否存在,如果不存在,则您自己创建它。
然后您将 2 MB 写入该临时文件夹。
突然,其他系统进程删除了您的临时文件夹,您无法再写入。
您无法以编程方式阻止这种情况,在某些系统中可能会发生这种操作(在 unix 中,root 用户可能执行 rm -rf /tmp 并且您无能为力。在 Windows 中,我认为系统不会让其他进程删除正在使用的文件)
通过强制您检查代码中的这种异常,平台设计人员认为至少您意识到了这一点。
乔恩是正确的,有时你无能为力,可能在程序死亡之前记录,这被认为是“处理异常”(糟糕的处理是的,但至少处理)
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 中的某个地方,并在 Dialog 消息中呈现给用户(而不是在没有进一步信息的情况下让应用程序消失在他的眼中)。当然,您无能为力来恢复该 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
也不
java.net.UnknownHostException
但取而代之的是
my.application.DataNotSavedException
并且不同的实现将在正确的级别处理异常,并将其转换为适当的抽象:
客户端代码:
DataSaver saver = DataServer.getSaverFor("someKeyIdString");
try {
saver.save( myData );
} catch( DataNotSavedException dnse ) {
// Oh well... .
ShowEndUserError("Data could not be saved due to : " dnse.getMessage() );
}
实现代码:
class ServerSaver implements DataSaver {
....
public void save( Data data ) throws DataNotSavedException {
// Connect the remore server.
try {
Socket socket = new Socket( this.remoteServer, this.remotePort );
OuputStream out = socket.getOut....
....
....
} catch ( UnknownHostException uhe ) {
// Oops....
throw new DataNotSavedException( uhe );
}
}
}
FileSaver 和 DatabaseSaver 会做类似的事情。
所有这些都是检查异常,因为编译器会让你检查它们。
何时使用其中一个(选中/未选中):这里
还有另外两种:这里
最后,运行时的一个更简单的解释是:这里