回答(14)

2 years ago

try {

final Resource resource = acquire();

try {

use(resource);

} finally {

resource.release();

}

} catch (ResourceException exx) {

... sensible code ...

}

任务完成 . 没有空测试 . 单一捕获,包括获取和释放异常 . 当然,您可以使用Execute Around习语,只需为每种资源类型编写一次 .

2 years ago

Streams实现 Closeable 因此,您可以为所有流重用该方法

protected void closeQuietly(Closeable resource) {

if (resource == null)

return;

try {

resource.close();

} catch (IOException e) {

//log the exception

}

}

2 years ago

如果您正在使用Java 7,并且 resource 实现 AutoClosable ,则可以执行此操作(使用InputStream作为示例):

try (InputStream resource = getInputStream()) {

// Use the resource.

}

catch( Exception ex ) {

// Problem with the resource.

}

2 years ago

我通常使用 org.apache.commons.io.IOUtils 中的一个 closeQuietly 方法:

public static void closeQuietly(OutputStream output) {

try {

if (output != null) {

output.close();

}

} catch (IOException ioe) {

// ignore

}

}

2 years ago

经过多次考虑后,我发现以下代码最佳:

MyResource resource = null;

try {

resource = new MyResource();

resource.doSomethingFancy();

resource.close();

resource = null;

} finally {

closeQuietly(resource)

}

void closeQuietly(MyResource a) {

if (a!=null)

try {

a.close();

} catch (Exception e) {

//ignore

}

}

该代码保证以下内容:

代码完成后释放资源

关闭资源时抛出的异常不会在不处理的情况下消耗掉 .

代码不会尝试关闭资源两次,也不会创建不必要的异常 .

2 years ago

我通常这样做:

try {

// Use the resource.

} catch( Exception ex ) {

// Problem with the resource.

} finally {

// Put away the resource.

closeQuietly( resource );

}

别处:

protected void closeQuietly( Resource resource ) {

try {

if (resource != null) {

resource.close();

}

} catch( Exception ex ) {

log( "Exception during Resource.close()", ex );

}

}

2 years ago

忽略'finally'块中发生的异常通常是一个坏主意,除非知道这些异常将是什么以及它们将代表什么条件 . 在正常的 try/finally 使用模式中, try 块将事物置于外部代码不期望的状态,并且 finally 块将这些事物的状态恢复为外部代码所期望的状态 . 捕获异常的外部代码通常会期望,尽管有异常,但所有内容都已恢复到 normal 状态 . 例如,假设某些代码启动一个事务,然后尝试添加两个记录; "finally"块执行"rollback if not committed"操作 . 调用者可能已准备好在执行第二个"add"操作期间发生异常,并且可能期望如果它捕获到这样的异常,则数据库将处于尝试任一操作之前的状态 . 但是,如果在回滚期间发生第二个异常,则如果调用者对数据库状态做出任何假设,则可能会发生错误 . 回滚失败代表了一个重大危机 - 一个不应该被期望仅仅"Failed to add record"异常的代码捕获的危机 .

我个人倾向于有一个finally方法捕获发生的异常并将它们包装在“CleanupFailedException”中,认识到这种失败代表了一个主要问题,并且不应该轻易 grab 这样的异常 .

2 years ago

我经常这样做:

MyResource r = null;

try {

// use resource

} finally {

if( r != null ) try {

r.close();

} catch( ThatSpecificExceptionOnClose teoc ){}

}

理由:如果我已经完成了资源并且我唯一的问题是关闭它,那么我无能为力 . 如果我已经完成了资源,那么杀死整个线程也没有意义 .

这是至少对我而言,忽略该检查异常是安全的情况之一 .

直到今天,我还没有使用这个成语的任何问题 .

2 years ago

一种解决方案,如果两个异常是两个不同的类

try {

...

}

catch(package1.Exception err)

{

...

}

catch(package2.Exception err)

{

...

}

finally

{

}

但有时你无法避免这种第二次尝试 . 例如关闭流

InputStream in=null;

try

{

in= new FileInputStream("File.txt");

(..)// do something that might throw an exception during the analysis of the file, e.g. a SQL error

}

catch(SQLException err)

{

//handle exception

}

finally

{

//at the end, we close the file

if(in!=null) try { in.close();} catch(IOException err) { /* ignore */ }

}

2 years ago

你可以将它重构成另一种方法......

public void RealDoSuff()

{

try

{ DoStuff(); }

catch

{ // resource.close failed or something really weird is going on

// like an OutOfMemoryException

}

}

private void DoStuff()

{

try

{}

catch

{

}

finally

{

if (resource != null)

{

resource.close();

}

}

}

2 years ago

如果可以,您应该进行测试以避免错误情况开始 .

try{...}

catch(NullArgumentException nae){...}

finally

{

//or if resource had some useful function that tells you its open use that

if (resource != null)

{

resource.Close();

resource = null;//just to be explicit about it was closed

}

}

此外,您应该只捕获可以恢复的异常,如果无法恢复,则将其传播到程序的顶层 . 如果您无法测试错误情况,则必须使用try catch块来包围代码,就像您已经完成的那样(尽管我建议仍然捕获特定的,预期的错误) .

2 years ago

从Java 7开始,您不再需要显式关闭 finally 块中的资源,而是可以使用 try -with-resources语法 . try-with-resources语句是一个声明一个或多个资源的try语句 . 资源是在程序完成后必须关闭的对象 . try-with-resources语句确保在语句结束时关闭每个资源 . 实现java.lang.AutoCloseable的任何对象(包括实现java.io.Closeable的所有对象)都可以用作资源 .

假设以下代码:

try( Connection con = null;

Statement stmt = con.createStatement();

Result rs= stmt.executeQuery(QUERY);)

{

count = rs.getInt(1);

}

如果发生任何异常,将按照创建它们的相反顺序在这三个资源中的每一个上调用 close 方法 . 这意味着将首先为ResultSetm调用close方法,然后调用Statement,最后调用Connection对象 .

同样重要的是要知道自动调用close方法时发生的任何异常都会被抑制 . 可以通过 Throwable 类中定义的 getsuppressed() 方法检索这些抑制的异常 .

2 years ago

可以说有点超过顶部,但如果你让异常冒出来并且你无法记录任何内容,那么它可能很有用在你的方法中(例如,因为它是一个库,你宁愿让调用代码处理异常和日志记录):

Resource resource = null;

boolean isSuccess = false;

try {

resource = Resource.create();

resource.use();

// Following line will only run if nothing above threw an exception.

isSuccess = true;

} finally {

if (resource != null) {

if (isSuccess) {

// let close throw the exception so it isn't swallowed.

resource.close();

} else {

try {

resource.close();

} catch (ResourceException ignore) {

// Just swallow this one because you don't want it

// to replace the one that came first (thrown above).

}

}

}

}

2 years ago

你为什么要避免额外的阻止?由于finally块包含可能引发异常的“正常”操作,并且您希望finally块完全运行,因此您必须捕获异常 .

如果你不希望finally块抛出异常并且你不知道如何处理异常(你只是转储堆栈跟踪)让异常冒泡调用堆栈(从最后删除try-catch)块) .

如果你想减少输入,你可以实现一个“全局”外部try-catch块,它将捕获finally块中抛出的所有异常:

try {

try {

...

} catch (Exception ex) {

...

} finally {

...

}

try {

...

} catch (Exception ex) {

...

} finally {

...

}

try {

...

} catch (Exception ex) {

...

} finally {

...

}

} catch (Exception ex) {

...

}

java finally 抛出异常,在finally块中抛出异常相关推荐

  1. java catch 抛出异常_java - 在catch和最后claus中抛出异常

    java - 在catch和最后claus中抛出异常 关于大学的Java问题,有这段代码: class MyExc1 extends Exception {} class MyExc2 extends ...

  2. java 同步块 抛出异常_不把 wait 放在同步块中,为啥这种情况不会抛出 IllegalMonitorStateException?...

    这是一个来自 Java 编程思想的例子,它只是想表达 sleep 的线程可中断,但同步 IO 等待资源,或同步获得锁失败的线程,是不可同步的. //: concurrency/Interrupting ...

  3. java中抛出异常快捷键_idea中处理异常的快捷键

    建议68:从System.Exception或其他常见的基本异常中派生异常 微软建议:从System.Exception或其他常见基本异常之一派生异常.在Visual Studio中输入Excepti ...

  4. java catch中抛出异常_简单了解Java编程中抛出异常的方法

    任何Java代码都可以抛出异常,如:自己编写的代码.来自Java开发环境包中代码,或者Java运行时系统.无论是谁,都可以通过Java的throw语句抛出异常.从方法中抛出的任何异常都必须使用thro ...

  5. java中主函数抛出的异常怎么解决_java – 从递归函数中抛出异常

    我为一个更大的应用程序构建了一个库/模块,它从函数中抛出异常.如果找不到文件或文件包含错误格式,则抛出Exeption. 该方法看起来像: Shape parse(String path) throw ...

  6. java8 foreach 异常_错误处理 – 在java 8流foreach中抛出异常

    我正在使用 java 8流,我不能在流的foreach中抛出异常. stream.forEach(m -> { try { if (isInitial) { isInitial = false; ...

  7. Jvm处理Java Thread 的run方法中抛出异常的流程

    Jvm处理Java Thread 的run方法中抛出异常的流程 参考文章: (1)Jvm处理Java Thread 的run方法中抛出异常的流程 (2)https://www.cnblogs.com/ ...

  8. 在finally块中使用try catch,并且catch的时候抛出异常的一个问题

    在finally块中使用try catch,并且catch的时候抛出异常的一个问题 参考文章: (1)在finally块中使用try catch,并且catch的时候抛出异常的一个问题 (2)http ...

  9. 在 catch 块中可以抛出异常吗?

    在 catch 块中是可以抛出异常的.当一个异常在 try 块中被捕获后,catch 块可以选择重新抛出该异常,以便将异常传递给更高级别的异常处理程序或让调用者知道发生了异常.在 catch 块中重新 ...

最新文章

  1. 浅析Web工程目录和tomcat目录
  2. SimpleUrlHandlerMapping 处理器映射的配置--转
  3. 二、【绪论】算法和算法评价
  4. buuctf (misc)神秘龙卷风 [brainfuck密码,压缩包密码爆破]
  5. 修改openwrt 编译 image的大小
  6. [云炬python3玩转机器学习笔记] 2-4批量学习、咋西安学习、参数学习和非参数学习
  7. 2018+计算机软件,2018年6月考试《计算机软件技术基础(1)》在线考核试题
  8. Angular应用input和div标签页的动态创建场景
  9. decimal类型 go_Go 语言程序设计——字符串类型(2)
  10. linux命令——init 的使用用法
  11. Linux通过进程号查询占用的端口
  12. tiny core linux ftp,tinycore 的基本搭建,开机时间只需要1-3秒
  13. 生活中有哪些越早明白越好的道理
  14. 在Visual Studio Code中查找并​​替换为换行符
  15. Spring MVC中的统一异常处理
  16. HIT软件构造 软件生命周期 配置管理
  17. 调用支付jsapi缺少参数appid
  18. MySQL高可用架构故障自动转移插件MHA
  19. 用VS新建多层架构时引用第三方dll 时清理解决方案时,放bin文件夹下的bll被清空问题
  20. 【去哪儿旅行】产品分析报告

热门文章

  1. stunnel4隧道工具
  2. 2015-01-23 记录我喜欢的文
  3. jquery简单多图片前后滚动插件
  4. 逻辑回归实战:从疝气病症预测病马的死亡率
  5. [iOS 代码混要加固转帖]
  6. 100行代码让你的代码跳起舞(视频转字符画)
  7. 网龙暑期训练营第三周:标准资源包的应用与岗哨、打靶任务的开发
  8. 数据结构:线性表(List)【详解】
  9. python爬取天气与每日一笑并通过微信发送
  10. 使用chrome调试平板/手机网页