概述:

Java中的异常机制是一个好东西。不过好东西也要正确地使用才行,不然就会让我们错误地认识它。在错误地认识状况下,就会错误地使用。这样就成了一个恶性地循环了。这不是我们愿意看到的。不要以为我们已经可以很好地使用异常了,下面就针对部分问题作一个讲解。这部分的问题中,有一些是来自《Effective Java》这本书中,有一部分是来自本人平时开发过程中遇到的。

本文链接:http://blog.csdn.net/lemon_tree12138/article/details/50474230 -- Coding-Naga
                                                                 --转载请注明出处

1.是throw还是try-catch

这个是一个对刚接触编程开发的人来说,经常面临但又选择不好的问题。

由于我们开发的项目可不是像写Demo一样轻松,这里可能会有很多层次结构。我们要在具体哪一层的什么位置是使用try-catch这个异常呢,还是把异常throw到上一层呢?这里,我们首先要知道一件事,那就是try-catch和throw分别会发生什么情况呢?

try-catch: 捕获一个异常情况,并中止try块中的后续操作。且不会再向上抛出异常了。

throw: 当使用throw抛出一个异常时,当前的执行块(方法)会结束后续的执行。相当于一个return操作,并保证了上层在调用的时候可以捕获到这个异常,并做相应处理。

Demo示例如下:

public class ExceptionClient {public static void main(String[] args) {ExceptionClient client = new ExceptionClient();client.showInfo();}private void showInfo() {try {System.out.println("first info");testException();System.out.println("second info");} catch (Exception e) {System.err.println(e);}System.out.println("outside info");}private void testException() throws AException {boolean f = true;if (f) {throw new AException("AException");}System.out.println("f is false.");}
}

按照上面对try-catch和throw的分析,可以知道,showInfo方法try块中的第二句话是不打印的,而testException方法的最后一句也是不打印的。结果如下:

图-1 try-catch测试结果

2.是使用受检的异常还是非受检的异常

首先我们要了解什么是受检异常和非受检异常,不过这里顾名思义,受检即接受检查。由于目前的IDE很是智能,当我们在使用受检异常而未try-catch这个异常时,IDE会给出错误提示。如下:

图-2 IDE对受检异常的检查

而非受检异常则不会被IDE识别。还有一点,因为前面说到IDE会检测到受检异常,所以,这里如果我们强行运行此代码,是通不过编译的,非受检异常则不会。

好了,说明了受检异常和非受检异常在使用过程中的区别。现在就来说说怎么创建这些不同的异常吧。

当我们要编写自定义的受检异常A.java时,A的class需要继承Exception,而非受检异常B.java则是继承RuntimeException

由于受检异常会在使用的过程,强行限制开发人员去try-catch。而在try-catch此异常的时候,开发人员则可以对此异常进行修正并重新之前的操作(即恢复)。在RuntimeException中则没有这样的限制。所以,当我们试图告诉调用者,当前的异常是可以被修复,并允许重新去调用的时候,我们就使用受检的异常,当我们认为这是一个程序错误的时候,则需要使用非受检异常。

可能对在何时使用受检异常或非受检异常有了一些基本认识,然后你可能会问这样的一个问题:我们不是还有一个Error么,那么错误(Error)和异常有什么区别呢?下面就列举了这两者之间的区别(点击查看参考来源):

Exception:
1.可以是可被控制(checked) 或不可控制的(unchecked)。
2.表示一个由程序员导致的错误。
3.应该在应用程序级被处理。
Error:
1.总是不可控制的(unchecked)。
2.经常用来用于表示系统错误或低层资源的错误。
3.如何可能的话,应该在系统级被捕捉。

3.只针对不正确的条件才使用异常

关于这一点,首先我们应该了解的是Java在进行异常检查时消耗的系统资源,要比普通的程序调用高。那么,如果我们的程序在不停地进行异常检查,就会对程序整个的性能产生不小的影响。我们可以从一个小例子中看出这一点。如下:

假设现有10000000个元素的List,我们要对此List进行遍历,有三种方式,分别如下:

第一种:对每一种情况进行异常检查

private void call_1(List<Integer> list) {long t = System.currentTimeMillis();try {int index = 0;while(true) {list.get(index++);} } catch (IndexOutOfBoundsException e) {LogUtils.printTimeUsed("不针对检查异常", t);}}

第二种:只对错误的情况进行异常检查

private void call_2(List<Integer> list) {long t = System.currentTimeMillis();t = System.currentTimeMillis();int size = list.size();int index = 0;while(true) {if (index >= size) {try {list.get(index++);} catch (IndexOutOfBoundsException e) {LogUtils.printTimeUsed("针对性检查异常", t);break;}}list.get(index++);}}

第三种:普通的循环遍历

private void call_3(List<Integer> list) {long t = System.currentTimeMillis();t = System.currentTimeMillis();int size = list.size();int index = 0;for (index = 0; index < size; index++) {list.get(index++);}LogUtils.printTimeUsed("循环遍历", t);}

测试结果:

图-3 不同异常检查方式遍历List

从上面的测试结果中,我们可以看到不针对地检查异常(盲目地检查异常),比有针对性地检查异常性能上低了不少。所以,我们在使用异常的时候,请格外谨慎。需要去避免一些不必要的异常检查,以优化我们的程序代码。

Ref:

《Effective Java》

Java:如何正确地使用异常详解相关推荐

  1. Java异常详解及如何处理

    来源:Java异常详解及如何处理 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言 ...

  2. Java内存模型(JMM)详解-可见性volatile

    这里写自定义目录标题 Java内存模型(JMM)详解-可见性 什么是JMM JMM存在的意义 为什么示例demo中不会打印 i 的值 如何解决可见性问题 **深入理解JMM内存模型** JAVA内存模 ...

  3. 牛客网 Java 工程师能力评估 20 题 - 详解

    牛客网 Java 工程师能力评估 20 题 - 详解 不知在看博客的你是否知道 牛客网,不知道就太落后了,分享给你 : 牛客网 此 20 题,绝对不只是 20 题! 免责声明:本博客为学习笔记,如有侵 ...

  4. java集合框架史上最详解(list set 以及map)

    title: Java集合框架史上最详解(list set 以及map) tags: 集合框架 list set map 文章目录 一.集合框架总体架构 1.1 集合框架在被设计时需满足的目标 1.2 ...

  5. java string()函数_转载java String.split()函数的用法详解

    转载java String.split()函数的用法详解 如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!在java.lang包中有String.split()方法的原型是: p ...

  6. 【转帖】windows命令行中java和javac、javap使用详解(java编译命令)

    windows命令行中java和javac.javap使用详解(java编译命令) 更新时间:2014年03月23日 11:53:15   作者:    我要评论 http://www.jb51.ne ...

  7. 【转】Java魔法堂:String.format详解

    Java魔法堂:String.format详解   目录     一.前言     二.重载方法     三.占位符     四.对字符.字符串进行格式化     五.对整数进行格式化     六.对 ...

  8. java之yield(),sleep(),wait()区别详解-备忘笔记

    java之yield(),sleep(),wait()区别详解-备忘笔记 1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如 ...

  9. Java中大数据数组,Java基础学习笔记之数组详解

    摘要:这篇Java开发技术栏目下的"Java基础学习笔记之数组详解",介绍的技术点是"java基础学习笔记.基础学习笔记.Java基础.数组详解.学习笔记.Java&qu ...

最新文章

  1. 一男子蒙冤入狱 10 天,竟是 AI 认错了!
  2. python 学习笔记8 (模块)
  3. GIF发明者感染新冠后去世,没有他就没有表情包
  4. 排序算法——冒泡排序、选择排序、直接插入排序
  5. jQuery.extend()方法
  6. leetcode 995. K 连续位的最小翻转次数(贪心算法)
  7. Win7旗舰版系统网页显示不全怎么办
  8. android系统(3)---dumpsys 知识学习
  9. 前端是Sencha Touch+ Cordova(转)
  10. left join, right join , inner join, join, union的意义
  11. tomcat设置子域名session共享以及修改JSESSIONID
  12. eucalyptus 云平台搭建
  13. [填坑]QT信号与槽机制注意事项
  14. linux微软雅黑字体库_Ubuntu 安装 Wine 4.4 并设置微软雅黑字体解决中文乱码
  15. HBuilderX接夜神Android模拟器调试
  16. mysql键值_如何在MySQL中存储键值对?
  17. org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias
  18. ES-JOB——分布式定时任务高级使用——控制台修改任务
  19. python numpy读取数据_python机器学习(七)数据分析利器,NumPy,pandas与Matplotlib
  20. memcache学习

热门文章

  1. C++ Primer 5th笔记(chap 15 OOP)抽象基类
  2. C++ Primer 5th笔记(chap 13 拷贝控制)三五法则
  3. java面试题2(java基础)
  4. LockSettingsService的setLockCredentialInternal函数详解
  5. 《格理论与密码学》笔记一
  6. 统计学要学的计算机课程有哪些,统计学专业主要课程学什么_课程设置安排及分类...
  7. 【安全漏洞】CVE-2021-32682 elFinder RCE 简单分析
  8. 2021算法竞赛入门班第三节课【堆、栈、队列、并查集】等习题
  9. 数据库视图的概念和相关操作合集
  10. ThreadLocal的使用