JDK并发工具包中,很多异常处理都使用了如下的结构,如AbstractExecutorService,即只有try和finally没有catch。

class X
{
private final ReentrantLock lock = new ReentrantLock();
// ... public void m()
{
lock.lock(); // block until condition holds
try
{
// ... method body
} finally
{
lock.unlock()
}
}
}

  

为什么要使用这种结构?有什么好处呢?先看下面的代码

public void testTryAndFinally(String name)
{
try
{
name.length();// NullPointerException
}
finally
{
System.out.println("aa");
}
}

传递null该方法的执行结果是:在控制台打印aa,并抛出NullPointerException。执行流程是先执行try块,出现异常后执行finally块,最后向调用者抛出try中的异常。这种执行结果是很正常的,因为没有catch异常处理器,所有该方法只能将产生的异常向外抛;因为有finally,所以会在方法返回抛出异常之前,先执行finally代码块中的清理工作。

这种做法的好处是什么呢?对于testTryAndFinally来说,它做了自己必须要做的事(finally),并向外抛出自己无法处理的异常;对于调用者来说,能够感知出现的异常,并可以按照需要进行处理。也就是说这种结构实现了职责的分离,实现了异常处理(throw)与异常清理(finally)的解耦,让不同的方法专注于自己应该做的事。那什么时候使用try-finally,什么时候使用try-catch-finally呢?很显然这 取决于方法本身是否能够处理try中出现的异常 。如果自己可以处理,那么直接catch住,不用抛给方法的调用者;如果自己不知道怎么处理,就应该将异常向外抛,能够让调用者知道发生了异常。即在方法的签名中声明throws可能出现而自己又无法处理的异常,但是在方法内部做自己应该的事情。

这可以参考ExecutorService.invokeAny()的方法签名

<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;

  转自 http://blog.csdn.net/aitangyong/article/details/38146833?utm_source=tuicool&utm_medium=referral

java只使用try和finally不使用catch的原因和场景的更多相关文章

  1. JAVA方法中的参数用final来修饰的原因

    JAVA方法中的参数用final来修饰的原因   很多人都说在JAVA中用final来修饰方法参数的原因是防止方法参数在调用时被篡改,其实也就是这个原因,但理解起来可能会有歧义,有的人认为是调用语句的 ...

  2. java中的throw、throws和try catch浅析

    今天在公司和同事聊天的时候,突然发现自己对java中的throw.throws和try catch的作用理解不够准确,在网上查了查,在此大概梳理一下. throw用于抛出异常,例如 throw new ...

  3. Java byte类型转换成int类型时需要 & 0XFF的原因

    Java byte类型转换成int类型时需要 & 0XFF的原因 假设有byte b  = -1; 那么b的二进制是:1111 1111. 如果将b直接转换为int类型,那么二进制是 1111 ...

  4. “全栈2019”Java第一百一十三章:什么是回调?回调应用场景详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. “全栈2019”Java第八十八章:接口中嵌套接口的应用场景

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. “全栈2019”Java第八十七章:类中嵌套接口的应用场景(拔高题)

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  7. java中File的delete()方法删除文件失败的原因

    java中File的delete()方法删除文件失败的原因 学习了:http://hujinfan.iteye.com/blog/1266387 的确是忘记关闭了: 引用原文膜拜一下: 一般来说 ja ...

  8. [转载]Java中异常的捕获顺序(多个catch)

    http://blog.sina.com.cn/s/blog_6b022bc60101cdbv.html [转载]Java中异常的捕获顺序(多个catch) (2012-11-05 09:47:28) ...

  9. java - 只输出中文, 包含中文标点符号

    在 Java 中直接使用Unicode 转码时会按照UTF-16LE 的方式拆分,并加上 BOM. 如果采用 UTF-16 拆分,在 Java 中默认采用带有 BOM 的 UTF-16BE 拆分. S ...

随机推荐

  1. CentOS6.6安装S******Sockets服务端

    1.查看系统 [root@localhost ~]# cat /etc/issue CentOS release 6.6 (Final) [root@localhost ~]# uname -a Li ...

  2. Spring事务异常回滚,捕获异常不抛出就不会回滚

    最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......    为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...

  3. openstack neutron 二/三层网络实现

    引用声明:https://zhangchenchen.github.io/2017/02/12/neutron-layer2-3-realization-discovry/ 一.概述 Neutron是 ...

  4. VS与SQL资源

    经常在网上看到有同学费尽心思的找SQL server数据库各版本的下载地址,看到别人的求助贴就不自觉的想去帮助他们,但是一个一个去帮助又不太现实,毕竟个人精力有限,既然大家有需求,那么笔者就本着乐于分 ...

  5. 【java】Java泛型

    一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: 1 public class GenericTest { 2 3 public static void main(Stri ...

  6. 域名 ip地址 端口号

    域名默认指定一个ip地址 当用域名访问网站的时候 网站会默认给个端口号80 或者自己指定 其他的 例如数据库 也是会给端口号 例如mysql 3306 域名:80 是访问iis 网站域名:3306 是 ...

  7. numpy 基于数值范围创建ndarray()

    基于数值范围创建函数创建ndarray 1 numpy.arange arange([start=0,] stop[, step=1,][, dtype=None]) >>> np. ...

  8. golang 学习笔记 ---make/copy/append

    package main import ( "fmt" ) func main() { a := [...]int{0, 1, 2, 3, 4, 5, 6, 7} s := mak ...

  9. dbms_random.seed

    语法: DBMS_RANDOM.SEED ( val IN BINARY_INTEGER); DBMS_RANDOM.SEED ( val IN VARCHAR2); val: Seed number ...

  10. xtrabackup-增量备份

    增量备份之所以能工作是因为每个innodb的page都包含日志序列号(LSN).LSN是整个数据库的版本号. 增量备份会拷贝那些LSN比备份开始时新的页.有两种算法用来计算查找这些页:第一种,支持所有 ...