【JavaSE】异常机制

异常指程序运行过程中出现的非正常现象,例如用户输入错误、除数为零、需要处理的 文件不存在、数组下标越界等。
所谓异常处理,就是指程序在出现问题时依然可以正确的执行完。
Java 是采用面向对象的方式来处理异常的。处理过程:

  • 抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个 对象,停止当前执行路径,并把异常对象提交给 JRE。
  • 捕获异常:JRE 得到该异常后,寻找相应的代码来处理该异常。JRE 在方法的调用 栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止。

一、异常分类

Java 对异常进行了分类,不同类型的异常分别用不同的 Java 类表示,所有异常的根类 为 java.lang.Throwable,Throwable 下面又派生了两个子类:Error 和 Exception。


Java 异常类层次结构图

1. Error

Error 是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编 写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java 虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java 虚拟机(JVM)一般会选择线 程终止。 Error 表明系统 JVM 已经处于不可恢复的崩溃状态中。我们不需要管他。


java.lang包下的Error类

2. Exception

Exception 是程序本身能够处理的异常,如:空指针异常(NullPointerException)、数 组 下 标 越 界 异 常 ( ArrayIndexOutOfBoundsException )、类 型 转 换 异 常 (ClassCastException)、算术异常(ArithmeticException)等。Exception 类是所有异常类的父类,其子类对应了各种各样可能出现的异常事件。
通常 Java 的异常可分为:

  1. RuntimeException 运行时异常
  2. CheckedException 已检查异常

3. RuntimeException

派生于 RuntimeException 的异常,如被 0 除、数组下标越界、空指针等,其产生比较频繁,处理麻烦,如果显式的声明或捕获将会对程序可读性和运行效率影响很大。 因此 由系统自动检测并将它们交给缺省的异常处理程序(用户可不必对其处理)。
这类异常通常是由编程错误导致的,所以在编写程序时,并不要求必须使用异常处理机 制来处理这类异常,经常需要通过增加“逻辑处理来避免这些异常”。
常见的运行时异常:

  1. ArithmeticException 异常:试图除以 0
public class Test3 { 
  public static void main(String[ ] args) { 
    int b=0; 
    System.out.println(1/b); 
  } 
}
image.png
  1. NullPointerException 异常
public class Test4 { 
  public static void main(String[ ] args) {
    String str=null; 
    System.out.println(str.charAt(0)); 
  } 
}
NullPointerException 异常
  1. ClassCastException 异常
class Animal{ 
}
class Dog extends Animal{
 }
class Cat extends Animal{ 
}
public class Test5 { 
  public static void main(String[ ] args) { 
    Animal a=new Dog(); 
    Cat c=(Cat)a; 
  } 
}
ClassCastException 异常
  1. ArrayIndexOutOfBoundsException 异常
public class Test6 { 
  public static void main(String[ ] args) {
    int[ ] arr = new int[5]; 
    System.out.println(arr[5]); 
  } 
}
ArrayIndexOutOfBoundsException 异常
  1. NumberFormatException 异常
public class Test7 { 
  public static void main(String[ ] args) {
    String str = "1234abcf"; 
    System.out.println(Integer.parseInt(str)); 
  } 
}
NumberFormatException 异常

4. CheckedException

所有不是 RuntimeException 的异常,统称为 Checked Exception,又被称为“已检 查异常”,如 IOException、SQLException 等以及用户自定义的 Exception 异常。 这类 异常在编译时就必须做出处理,否则无法通过编译。
异常的处理方式有两种:使用“try/catch”捕获异常、使用“throws” 声明异常。

二、异常捕获

捕获异常是通过 3 个关键词来实现的:try-catch-finally。用 try 来执行一段程序,如 果出现异常,系统抛出一个异常,可以通过它的类型来捕捉(catch)并处理它,最后一步 是通过 finally 语句为异常处理提供一个统一的出口,finally 所指定的代码都要被执行 (catch 语句可有多条;finally 语句最多只能有一条,根据自己的需要可有可无)。

try{
  可能出现异常的代码
}catch(异常类型 变量名){
  出现异常时执行的代码
}....catch(异常类型 变量名){
  出现异常时执行的代码
}finally{
  最后要执行的代码
}

注意:

  1. 一个try后可以有1~n个catch
  2. catch是从上到下依次判断执行,try中没有出现异常,不会执行catch判断捕获。一旦出现异常,try中后面的代码不会执行
  3. 如果catch中捕获的异常类型比较大,应放在最后
  4. finally:当前try ... catch的结构执行结束后,会执行finally中的代码(一般为释放资源的代码)
    例:
public class Test8 { 
  public static void main(String[ ] args) { 
    FileReader reader = null; 
    try {
      reader = new FileReader("d:/a.txt"); 
      char c = (char) reader.read(); 
      char c2 = (char) reader.read(); 
      System.out.println("" + c + c2); 
    } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } finally {
      try {
         if (reader != null) { 
           reader.close(); 
         } 
      } catch (Exception e) {
           e.printStackTrace(); 
      } 
    } 
  } 
}

三、声明异常

当 CheckedException 产生时,不一定立刻处理它,可以再把异常 throws 出去。
在方法中使用 try-catch-finally 是由这个方法来处理异常。但是在一些情况下,当前方法并不需要处理发生的异常,而是向上传递给调用它的方法处理。
如果一个方法中可能产生某种异常,但是并不能确定如何处理这种异常,则应根据异常规范在方法的首部声明该方法可能抛出的异常。
如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号隔开。

public static void readFile(String fileName) throws FileNotFoundException, IOException {
        FileReader in = new FileReader(fileName);
        int tem = 0;
        try {
            tem = in.read();
            while (tem != -1) {
                System.out.print((char) tem);
                tem = in.read();
            }
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

四、try-with-resource 自动关闭 Closable 接口的资源

public class Test8 {
    public static void main(String[] args) {
        try (FileReader reader = new FileReader("d:/a.txt");) { //try-with-resource
            char c = (char) reader.read();
            char c2 = (char) reader.read();
            System.out.println("" + c + c2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

五、自定义异常

  • 在程序中,可能会遇到 JDK 提供的任何标准异常类都无法充分描述清楚我们想要 表达的问题,这种情况下可以创建自己的异常类,即自定义异常类。
  • 自定义异常类只需从 Exception 类或者它的子类派生一个子类即可。
  • 自定义异常类如果继承 Exception 类,则为受检查异常,必须对其进行处理;如果不想处理,可以让自定义异常类继承运行时异常 RuntimeException 类。
  • 习惯上,自定义异常类应该包含 2 个构造器:一个是默认的构造器,另一个是带 有详细信息的构造器。
class IllegalAgeException extends Exception {
    public IllegalAgeException() {
    }//带有详细信息的构造器,信息存储在 message 中 

    public IllegalAgeException(String message) {
        super(message);
    }
}

自定义异常的使用:

public void setAge(int age) throws IllegalAgeException { 
  if (age < 0) { 
    throw new IllegalAgeException("人的年龄不应该为负数"); 
  }
  this.age = age; 
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • 什么是异常? 异常本质上是程序上的错误,错误在我们编写程序的过程中会经常发生,包括编译期间和运行期间的错误。 编译...
    若兮缘阅读 3,357评论 0 11
  • 目录介绍 1.什么是异常 2.异常2.1 异常的概述和分类【了解】2.2 JVM默认是如何处理异常的【理解】2.3...
    杨充211阅读 316评论 0 1
  • 2.JAVA异常 异常指不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。异常是一个事件,它发生在程...
    青城楼主阅读 555评论 0 0
  • 通俗编程——白话JAVA异常机制 - 代码之道,编程之法 - 博客频道 - CSDN.NEThttp://blog...
    葡萄喃喃呓语阅读 3,179评论 0 25
  • 概念介绍 异常是发生在程序执行过程中阻碍程序正常执行的错误事件,当一个程序出现错误时,可能的情况有如下3种: 语法...
    niaoge2016阅读 5,178评论 2 20