Java异常处理机制 —— 深入理解与开发应用

  本文为原创博文,严禁转载,侵权必究!

  Java异常处理机制在日常开发中应用频繁,其最主要的不外乎几个关键字:try、catch、finally、throw、throws,以及各种各样的Exception。本篇文章主要在基础的使用方法上,进一步分析在开发中如何使用异常机制更合理。

  • try-catch-finally

    try-catch-finally块的用法比较简单,使用频次也最高。try块中包含可能出现异常的语句(当然这是人为决定的,try理论上可以包含任何代码),catch块负责捕获可能出现的异常,finally负责执行必须执行的语句,这里的代码不论是否发生了异常,都会被执行。

    针对这部分,因为很基础,所以就提几点比较关键的建议:

      1、当你在写try-catch语句的时候,脑子里是知道自己要去针对哪种异常进行处理的,不要只是以防万一,加了个catch(Exception e),这是毫无意义的。并且,一个try块中可能有多个异常,对于每一类异常,要分别写一个catch进行捕获。       

      2、针对可能出现异常的语句进行try-catch,大段代码的try-catch会非常不利于维护代码时定位异常可能发生的位置,对于肯定不会发生异常的稳定的代码,不需要放在try块中。

      3、try-catch虽然在功能上,可以成为流程控制的工具,达到条件分支的效果。但相比于if-else语句,java的异常处理机制基于面向对象的思想,使用过程中需要更多的时间与空间的开销,所以不要用异常机制去做基本的条件判断,只有在程序会因为异常而中断时进行捕获和处理。

      4、finally块中永远不要写return语句,因为finally块中总是最后执行,他会改变预期在try和catch块中的返回值(举个例子,你在catch中捕获了一个异常并抛出e,又在finally语句中return true,这样你抛出的异常就"消失"了,因为当前函数的执行结果已经从抛出异常 转变成 return true)。另外,在使用资源对象与流对象时,finally块必须对资源对象、流对象进行关闭。

  • Java异常体系结构

    Java异常体系的基类是Throwable,它主要有两个子类:Error 和 Exception。其结构如下图:

      

    上图中,Error是指程序无法处理的错误,多指系统内部比较严重的错误。大多数这类错误与开发人员无关,我们关注的主要是Exception。

    Exception主要分为两块:运行时异常和非运行时异常。RuntimeException及其子类都称为运行时异常;除此之外, 所有Exception的子类异常都是非运行时异常。

    运行时异常多指程序逻辑上出现问题(也就是我们自己写代码逻辑出了问题),常见的错误包括 ClassCastException:类型转换异常、NullPointerException:空指针异常、IndexOutOfBoundsException:越界异常...这些异常都可以通过程序逻辑处理来避免(比如加一个判断语句判断是否越界、是否属于某类型、是否为null),所以编译器把这些工作交给了程序员来把控,在编译期即使手动抛出了一个运行时异常不去捕获,编译器也会通过。因而这类异常也叫做"未检查异常"(uncheck)。同样属于未检查异常的还有所有的Error。即上图中,所有蓝色框表示未检查异常,橙色框表示"检查异常"(check)。对于检查异常,在可能发生异常的位置需要用try-catch块去捕获并处理,如果不处理它,就会一直向上层调用抛出,直到被处理为止。

  • throw 与 throws

    throws关键字主要在方法签名中使用,用于声明该方法可能抛出的异常。throws 可以理解成是一种通知行为,没有实际的抛出异常的动作,而仅仅是告诉调用他的上层函数,这里可能会抛出这个异常;

    throw用于在函数体内语句中,表示抛出一个实际的异常的实际动作,如果在函数内没有捕获并处理,那么将会一直向上抛出这个异常直到被main()/Thread.run()抛出。

    当一个函数throws声明函数可能抛出一个非运行时异常(检查异常)时,那么即使这个函数内部不显示使用throw,调用它的上层函数也必须包含处理这个异常的代码。举个例子:

public class Main {

    public static void main(String[] args){

        exceptionTest();
    }
    static int exceptionTest() throws IOException {

        return 0;
    }
}

    上述代码中调用的exceptionTest函数声明抛出一个IOException属于检查异常,哪怕exceptionTest函数中不可能抛出这个异常,调用它的函数也必须对此异常做出捕获处理。现在main函数中没有相关的处理逻辑,所以会编译错误,如下图:

    而对运行时异常,就是另一种情况了:

 1 public class Main {
 2
 3     public static void main(String[] args){
 4
 5         int i = divideTest(0);
 6         System.out.println(i);
 7     }
 8     static int divideTest(int b) throws ArithmeticException {
 9
10         int i = 5/b;
11         return i;
12     }
13 }

    同样在main函数没有处理异常的逻辑,这次声明抛出的异常是ArithmeicException,他属于运行时异常(RuntimeException),所以编译器对声明的抛出置之不理:

        

    虽然编译期通过,但在运行时程序仍然会自动抛出运行时异常,并一直向上抛出到Main函数。而Main()中没有对该异常的捕获处理,所以主线程终止。

    结论:我目前的理解是,throws一个运行时异常是没有任何实际意义的,除非你为了遵循某个统一的规范而这样做。throws 存在的意义主要是将可能的非运行时异常交给编译器把关,让编译器监督开发人员对这些异常进行捕获处理。

    另外,当你需要自定义一个异常时,如果需要在编译期检查,并在上层统一处理,那么直接继承Exception成为一个检查异常;如果不需要编译期检查,抛出异常表示程序异常需要直接中断,那么继承RuntimeException成为一个运行时异常即可。

时间: 2024-12-25 22:03:46

Java异常处理机制 —— 深入理解与开发应用的相关文章

java异常处理机制 -简单理解

说明:(1)异常是指 java 程序运行时(非编译)所发生的非正常情况或错误. (2) Error 表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题.         (3) Exception 表示程序还能够克服和恢复的问题.分为普通异常和系统异常.                 普通异常:也称checked异常,是运行环境的变化或异常所导致的问题,是用户能够克服的问题.如网络掉线,硬盘空间不足等.                 系统异常

【转】深入理解java异常处理机制

深入理解java异常处理机制 1. 引子 try-catch-finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解.不过,我亲自体验的"教训"告诉我,这个东西可不是想象中的那么简单.听话.不信?那你看看下面的代码,"猜猜"它执行后的结果会是什么?不要往后看答案.也不许执行代码看真正答案哦.如果你的答案是正确,那么这篇文章你就不用浪费时间看啦. <span style="background-color: rg

Java 异常处理机制和集合框架

课程  Java面向对象程序设计   实验名称  异常处理机制.集合框架 班级    13级计三          学号  10503                姓名 一.实验目的 掌握面向对象程序设计技术 二.实验环境 1.微型计算机一台 2.WINDOWS操作系统,Java SDK,Eclipse开发环境 三.实验内容 1.Java异常处理机制涉及5个关键字:try.catch.finally.throw.throws,请理解每个关键字的作用,并在编写程序,使用运用这5个关键字,观察效果

Java异常处理机制就是程序代码执行过程

我也是通过各种方式在进行验证是否可以满足我们的需求,今天我就发现了一个问题.现在我们来一起说明一下,这个可能不算是bug,而应该需要我们记住就可以了. 对于一副灰度图像I,她的每一个像素点I(x,y)都有一个灰度值,一般情况下可能的灰度取值有2^8=256个(0,1,...,255).如果我们统计出灰度值r在I中出现的次数n,并对其进行归一化(n/N,N是所有灰度值出现次数的总和),这样我们就可以得到像素r在I中出现的概率p(r).如果对每一个可能的灰度取值r都做同样的处理,我们可以得到如图1左

Java异常处理机制很有意思

前言:在网络上看到一篇<深入理解Java异常处理机制>,看完感觉自己也有一点小想法,的确在很多Java学者的眼里,异常处理机制不就是try catch finally吗,有啥好理解,很多时候,我也经常忽略这方面的内容,感觉没什么有意思的,那么我们来扎个小马步吧 1.经过对原作者的例子改造 package mwq; public class T1 { public static void main(String[] args) { boolean b = true; try { b = tb1(

如何正确使用Java异常处理机制

第一节 异常处理概述 第二节 Java异常处理类 2.1 Throwable 2.1.1 Throwable有五种构造方法 2.1.2 Throwable的所有成员方法 2.2 Error 2.3 Exception 2.4 RuntimeException 2.5 Checked Exception 2.6 Uncheck Exception 2.7 总结 第三节 Java异常处理执行流程探究 3.1 流程一 3.2 流程二 3.3 流程三 3.4 流程四 3.5 流程五 3.6 流程六 3.

Java异常处理机制:try...catch...的执行流程

Java异常处理机制:try...catch...的执行流程 在项目中遇到try...catch...语句,因为对Java异常处理机制的流程不是很清楚,导致对相关逻辑代码不理解.所以现在来总结Java异常处理机制的处理流程: 1.异常处理的机制如下: 在方法中用 try... catch... 语句捕获并处理异常,catch 语句可以有多个,用来匹配多个不同类型的异常. 对于处理不了的异常或者要转型的异常,在方法的声明处通过 throws 声明异常,通过throw语句拋出异常,即由上层的调用方法

Java异常处理机制的秘密

一.结论 这些结论你可能从未听说过,但其正确性是毋庸置疑的,不妨先看看: 1.catch中throw不一定能抛回到上一层,因为finally中的return会抑制这个throw2.finally中throw一定能抛回上一层,因为此时其后的return不会被执行到(throw中断了正常的顺序流)3.在try/catch中return并不会直接返回上一层,而是先执行finally再返回 二.一段小程序 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

java异常处理机制详解

java异常处理机制详解 程序很难做到完美,不免有各种各样的异常.比如程序本身有bug,比如程序打印时打印机没有纸了,比如内存不足.为了解决这些异常,我们需要知道异常发生的原因.对于一些常见的异常,我们还可以提供一定的应对预案.C语言中的异常处理是简单的通过函数返回值来实现的,但返回值代表的含义往往是由惯例决定的.程序员需要查询大量的资料,才可能找到一个模糊的原因.面向对象语言,比如C++, Java, Python往往有更加复杂的异常处理机制.这里讨论Java中的异常处理机制. 异常处理 Ja