“欲渡黄河冰塞川,将登太行雪满山。” 系统运行,风云不测,睹始知终,秋去冬来,一叶落而知秋。

1. 什么是异常?

所有使我们程序提前终止,或者没有向预想方向去执行的错误统称为异常。

2. 异常的分类?

所有异常都由Throwable 继承而来,即ExceptionError都继承自Throwable

注:Java中只有Throwable类型的实例才可以被抛出(throw)或者捕获(try..catch)

(1)Error

Error是指在正常情况下不太可能出现的错误,它与代码的编写无关。通常是表示运行时JVM出现的问题,比如系统内部错误、或者资源不足等。

常见的有: OutOfMemoryError( 内存溢出 ) 、 VirtualMachineError(虚拟机错误)、 NoClassDefFoundError(类定义错误)

(2)Exception

Exception是指程序运行时,可以预料到的错误,Exception又分为以下两类

  • 可检查异常 (Exception)

    需要我们在程序中必须进行显式的捕获处理,否则将会编译报错,比如常见的有IOException、SQLException

  • 不可检查异常 ( RuntimeException ):

    常见的有NullPointerException(空指针)、ArrayIndexOutOfBoundException(下标越界异常)。是否需要去捕捉,程序本身不要求我们强制去做这些。但是可以避免代码在运行过程中的逻辑错误。

注意:

阿里Java开发手册中提到,如果可以进行预检测的RuntimeException不应该通过catch的方法进行处理。比如NullPointExceotion。可以先进行非控的判断,比如if(obj != null){…}

看了上面的内容,也就很轻松的去应对面试官问的问题 『Exception和Error有什么区别?』 当然,异常处理常作为面试过程中的夺命连环call。为了方便加深上面问题的答案,从网上找到了一张图。

3.异常处理

代码中的异常处理主要针对可检查异常。

(1)通过try…catch 语句来处理

(2)通过throws/throw将异常抛出交给上层处理

4.异常处理注意事项

1、谨慎使用异常处理

try..catch会造成程序的额外开销,所以建议只捕获关键的代码,切忌不要用try包住一个很大的代码块。

Java每实例化一个Exception,就会对当时的栈进行快照。如果操作比较频繁,那么对资源的开销就不能被忽略。

2、在finally代码块中对资源进行清理

如下代码,正常执行时没有任何问题,但是在关闭资源之前一旦出现异常,就会造成资源无法释放。

3、不要用异常做流程控制,条件控制

异常设计的初衷是为了解决程序运行中的各种意外情况,切异常处理的效率比条件判断的要低很多

4、catch时,请分清稳定代码和不稳定代码

稳定代码指的是无论如果都不会再出错的代码,对于非稳定代码进行catch时,尽可能区分异常类型,再做对应的异常处理。

灵魂三问:

  1.  哪里发生了异常?
  2.  谁来处理异常?
  3.  如何处理异常?

首先需要明确异常在哪里发生,在代码中是通过try-catch来发现异常的,但是有些程序员将大段代码定义在一个try-catch语句块中,这样非常不便于定位问题,是一种不负责任的做法。捕获异常时,要分稳定代码,和非稳定代码;

  • 稳定代码:无论如何都不会发生异常的代码;例如 int a = 0;
  • 异常捕获:针对非稳定的代码,捕获时要取分异常类型,并做相应的处理;

其次,判断谁来处理异常,先区分 throw 和throws的区别:

  • throw : 方法内部抛出具体异常类对象的关键字
  • throws:  (1)作用在方法的声明上,表示如果抛出异常,则由该方法的调用者来进行异常处理;(2)主要的声明这个方法会抛出会抛出某种类型的异常,让它的使用者知道捕获异常的类型。(3)出现异常是一种可能性,但不一定会发生异常。

了解了throw和throws的区别后,再来判断当前捕获的异常是否需要自己处理,如果异常在当前方法的处理范围之内,且没有必要对外透出,那么就直接捕获异常并做相应的处理,否则向上抛出,由上层方法或者框架来处理。

异常分类结构

try 代码块

Try—catch—finally 是处理异常的三部曲;但是不能只有try这个光杆司令;

  • try代码块:监视代码执行过程,一旦发生异常则直接跳转至catch,如果没有catch,则直接跳转至finally;
  • catch代码块:可选执行的代码块,如果没有任何异常发生,则不会执行,如果发生异常则进行处理或向上抛出,这一切都在catch代码块中执行。
  • finally代码块:必选执行的代码块,不管是否异常发生,即使发生 OutOfMemeryError也会执行,通常用于处理善后的清理工作;

注意:

(1)finally是在return表达式后执行的,此时简要return的结果已经被暂存起来,待finally代码块执行后将暂存的结果返回;

(2)不管程序代码块是否处于try块中,甚至包括catch块中代码,只要执行该代码时出现了异常,系统都会自动生成一个异常对象,如果程序没有为这段代码定义任何catch块,java运行环境肯定找不到处理该异常的catch块,程序肯定在此退出。

(3)try块后可以有多个catch块,try块后使用多个catch块是为了针对不同异常类提供的不同的异常处理方式。当系统发生不同意外情况时,系统会生成不同的异常对象,java运行时就会根据该异常对象所属的异常类来决定使用哪个catch块来处理该异常。

(4)通常情况下,如果try块被执行一次,则try块后只有一个catch块会被执行,绝不可能有多个catch块被执行,除非在循环中使用类continue开始下一次循环,下一次循环又重新运行了try块,这才可能导致多个catch块被执行。

(5)进行异常捕获时,一定要记住先捕获小的异常,再捕获大的异常

5.遇到的问题

  1. finally和try中的return哪个先执行?
  • try中有return, 会先将值暂存到本地变量中,无论finally语句中对该值做什么处理,最终返回的都是try语句中的暂存值。
  • 当try与finally语句中均有return语句,会忽略try中return。

相关文章

  1. 详解面试中常被问到的那些异常问题

6. try-with-resource如何优雅的关闭io流

JAVA的一大特性就是JVM会对内部资源实现自动回收,即自动GC,给开发者带来了极大的便利。但是JVM对外部资源的引用却无法自动回收,例如数据库连接,网络连接以及输入输出IO流等,这些连接就需要我们手动去关闭,不然会导致外部资源泄露,连接池溢出以及文件被异常占用等。

传统的手动释放外部资源一般放在一般放在try{}catch(){}finally{}机制的finally代码块中,因为finally代码块中语句是肯定会被执行的,即保证了外部资源最后一定会被释放。同时考虑到finally代码块中也有可能出现异常,finally代码块中也有一个try{}catch(){},这种写法是经典的传统释放外部资源方法,显然是非常繁琐的。

6.1 传统写法操作io流

例如如下读取的文件的io流,我们之前可能会这样写

public class Main {public static void main(String[] args) {FileInputStream fileInputStream =null;try {fileInputStream = new FileInputStream(new File("/Users/laoniu/a.txt")); //打开流byte[] bytes = new byte[1024];int line = 0;    //读取数据while ((line = fileInputStream.read(bytes))!= -1){System.out.println(new String(bytes,0,line));}} catch (IOException e) {e.printStackTrace();}finally {if (fileInputStream != null){ //不为空try {fileInputStream.close(); //关闭流} catch (IOException e) {e.printStackTrace();}}}}
}

6.2 使用try-with-resource写法优雅操作io流

try-with-resources 是 JDK 7 中一个新的异常处理机制,它能够很容易地关闭在 try-catch 语句块中使用的资源。所谓的资源(resource)是指在程序完成后,必须关闭的对象。try-with-resources 语句确保了每个资源在语句结束时关闭。所以实现了 java.lang.AutoCloseable 接口(其中,它包括实现了 java.io.Closeable 的所有对象),可以使用作为资源。

public class Main {public static void main(String[] args) {//把打开流的操作都放入try()块里try( FileInputStream fileInputStream = new FileInputStream(new File("/Users/laoniu/a.txt"))) {byte[] bytes = new byte[1024];int line = 0;while ((line = fileInputStream.read(bytes))!= -1){System.out.println(new String(bytes,0,line));}} catch (IOException e) {e.printStackTrace();}}
}

在try()中可以编写多个文件io流或网络io流。让我们看看java编译器是怎么帮我们实现的

借助idea查看编译后的代码

可以看到编译后的代码,java编译器自动替我们加上了关闭流的操作。所以跟我们自己关闭流是一样的。try-with-resource这样优雅的写法还是不错的,让代码看起来不那么臃肿。

注意jdk1.7以后才可以用,更多请关注官网:https://docs.oracle.com/javase/8/docs/technotes/guides/language/try-with-resources.html

  • JDK 7 引入的 try-with-resources 语句的原理和用法,以及介绍了 JDK 9 对 try-with-resources 的改进,使得用户可以更加方便、简洁的使用 try-with-resources 语句。
  • 作为 Milling Project Coin 的一部分, try-with-resources 声明在 JDK 9 已得到改进。如果你已经有一个资源是 final 或等效于 final 变量,您可以在 try-with-resources 语句中使用该变量,而无需在 try-with-resources 语句中声明一个新变量。

相关文章

  1. try - with - resource

【Java基础知识】 异常处理机制相关推荐

  1. Java基础知识——异常处理

    目录 异常概述 异常体系结构 异常的分类 ​ 常见异常举例 ​ ​ 异常处理方式 方式一:try-catch-finally finally的使用 方式二:throws 手动抛出异常 自定义异常 异常 ...

  2. JAVA基础知识+基础代码

    Java基础知识 异常处理 try {} catch(Exception e) {} void work() throws Exception {} //抛出异常 throw new Exceptio ...

  3. 【转】Java基础知识整理

    本博文内容参考相关博客以及<Java编程思想>整理而成,如有侵权,请联系博主. 转载请注明出处:http://www.cnblogs.com/BYRans/ PDF版下载链接:<Ja ...

  4. 《Java和Android开发实战详解》——1.2节Java基础知识

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第1章,第1.2节Java基础知识,作者 陈会安,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

  5. java 基础知识总结

    Java基础知识总结 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java语言代码把思 ...

  6. 【转】java基础知识总结

    Java基础知识总结 本博文内容参考相关博客以及<Java编程思想>整理而成,如有侵权,请联系博主. 转载请注明出处:http://www.cnblogs.com/BYRans/ PDF版 ...

  7. java(5)---Java基础知识大全

    Java基础知识大全 一.基础知识:  1.JVM.JRE和JDK的区别:  JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性.  java语言是跨平 ...

  8. Java基础知识(七) 输入输出流

    Java基础知识 输入输出流 1. Java IO流的实现机制是什么 2. 管理文件和目录的类是什么 3. Java Socket是什么 4. Java NIO是什么 5. 什么是Java序列化 6. ...

  9. java基础知识-----转

    基础知识: 1.C++或Java中的异常处理机制的简单原理和应用. 当J***A程序违反了J***A的语义规则时,J***A虚拟机就会将发生的错误表示为一个异 常.违反语义规则包括2种情况.一种是J* ...

  10. java基础知识之加强

    Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...

最新文章

  1. 【PL/SQL】Excel批量往数据库中插入数据:
  2. 您在2016年会做什么? Apache Spark,Kafka,Drill等
  3. 第一季1:HI3518EV200的体验
  4. VBA各种查询方法介绍和应用举例
  5. 属性定义为 not null unique_Spring Data with MySQL (实体定义)
  6. javascript设计模式-适配器模式
  7. 服务器装哪个操作系统好,服务器装哪个操作系统好
  8. 【Yarn】工作机制及任务提交流程
  9. Linux Tricks —— 快速清空文本文件内容、文本内容追加(tee)
  10. 为确保网络中不同计算机,在计算机网络中,为确保网络中不同计算机之间能正确地传送和接收数据,它们必须遵循一组共同的规则和约定。这些规则、约定或标准通常被称为____。...
  11. oracle迁移数据到mysql
  12. MacOS系统离线安装包11.x-12.x
  13. 计算机音乐新年好呀,新年好呀新年好 伴奏
  14. 简述数字电路在计算机的应用,数字电路应用举例
  15. 最简单DIY基于ESP8266的智能彩灯⑤(用C#调色板UI通过串口控制WS2812彩灯)
  16. 新手小白如何做自媒体自媒体入门视频教程(3G教程)
  17. SoundPool循环播放
  18. 12 款适用于开发人员的最佳 Web 开发软件
  19. 关于Python3爬虫抓取豆瓣电影的案例-利用正则表达式
  20. LATTICE FPGA 工具介绍之ACTIVE-HDL 建立工程及仿真步步来(2)

热门文章

  1. 基于golang的Json选择器
  2. 元宇宙产业委与南京信息工程大学举办“元宇宙与智能技术创新论坛”
  3. 关于使用preparestatement来实现模糊查询
  4. group by 与 where, having以及顺序
  5. Matlab数组,复数数组实部、虚部、模、幅角
  6. SkeyeVSS以智能手段助力乘梯消防安全电梯AI智能监控解决方案
  7. 刘源谷俊山黑龙江八一农垦大学教务网络管理系统
  8. 《鬼谷子本经阴符七术》原文全文
  9. 小米android q适配机型,小米官方公布安卓Q适配机型以及内测时间:最早2019年Q4季度开始...
  10. 增量编码器与Arduino连接(读取编码器脉冲数)