• java中的异常


    概念

    什么是异常?

    程序在运行期发生的不正常的事件,它会打断指令的正常执行流程

    异常的作用?

    增强程序的健壮性。

    Java语言使用异常处理机制为程序提供了异常处理能力

    Java语言中异常是以什么形式存在的呢?

    异常在java中以类的形式存在,每一个异常类都可以创建异常对象

    异常的分类

    Java程序运行过程中所发生的异常事件从严重性可分为两类:

    1. 错误(Error)

      JVM系统内部错误或资源耗尽等严重情况-属于JVM需要负担的责任,这一类异常事件无法恢复或不可能捕获,将导致应用程序中断。

    2. 异常(Exception)

      其它因编程错误或偶然的外在因素导致的一般性问题。这类异常得到恰当的处理时,程序有机会恢复至正常运行状况

      1. 非受检(unchecked)异常(运行时异常 RuntimeException)

        编译器不要求强制处置的异常。一般是指编程时的逻辑错误。是程序员应该积极避免其出现的异常

        java.lang.RuntimeException及它的子类都是非受检异常:

        1. 错误的类型转换:java.lang.ClassCastException

        2. 数组下标越界:java.lang.ArrayIndexOutOfBoundsException

        3. 空指针访问:java.lang.NullPointerException

        4. 算术异常(除0溢出):java.lang.ArithmeticException

      2. 受检(checked)异常 --- 一般性异常(编译时异常 所有Exception直接子类)

        编译器要求必须处置的异常。指的是程序在运行时由于外界因素造成的一般性异常。

        由于外界因素造成的一般性异常:

        1. 没有找到指定名称的类:java.lang.ClassNotFoundException

        2. 访问不存在的文件:java.io.FileNotFoundException

        3. 操作文件时发生的异常:java.io.IOException

        4. 操作数据库时发生的异常:java.sql.SQLException

    异常的处理机制

    1. Java程序在执行过程中如果出现异常,会自动生成一个异常类对象,该异常对象将被自动提交给JVM,这个过程称为抛出(throw)异常

    2. 当JVM接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常和处理异常

    3. 如果JVM找不到可以捕获异常的代码,则运行时系统将终止,相应的Java程序也将退出。

    注解:所有异常都是发生在运行阶段的。

    异常的处理方式

    1. 捕获异常

      使用try...catch语句进行异常的捕捉

      1 try{
      2     ......  //可能产生异常的代码 
      3 }catch( ExceptionName1 e ){
      4     ......  //异常的处理代码 
      5 }catch( ExceptionName2 e ){
      6     ......   //异常的处理代码 
      7 } finally{
      8     ......   //无论如何都会执行的语句 
      9 }

      注解:

      1. try 代码段包含的是可能产生异常的代码

      2. 1) try 代码段后跟一个或多个catch代码段。(或跟一个finally代码段)

      3. 当异常发生时,程序会中止当前的流程去执行相应的catch代码段

      4. 写catch代码时,先捕获的异常的范围不能大于后捕获的异常的范围。大的异常要写在后面

        例如:

        1 try{
        2      //...可能会报异常的代码
        3     }catch(ClassNotFoundException e){//小的异常
        4         e.printStackTrach();//catch括号里面可以是具体的类型异常,也可以是该异常类型的父类型异常
        5     }catch(Exception e){//大的异常
        6         e.printStackTrach();
        7     }
      5. finally段的代码无论是否发生异常都执行

      6. java 8新特性:一个catch代码可以可以声明多个能处理的特定异常的类型,多个类型之间用”|”隔开

        例如:catch( ExceptionName1 | ExceptionName2 e){

        ...... //异常的处理代码

        }

       1  public static void main(String[] args){
       2         try {
       3             method();
       4         } catch (ClassNotFoundException | FileNotFoundException e) {
       5             e.printStackTrace();
       6         }
       7         //这就是try...catch语句捕捉异常
       8     }
       9     public static void method() throws ClassNotFoundException,FileNotFoundException  {
      10         System.out.println("我是方法");
      11     }
    2. throws抛出异常类型(类似于推卸责任)

      在方法的位置上,使用throws关键字抛出异常,抛给上一级,谁调用就抛给谁,如果异常不处理继续往上抛,最终抛给main()方法,main()方法继续往上抛,抛给了JVM,JVM只有一个结果,使java程序终止

      例如:

       1 public static void main(String[] args) throws FileNotFoundException{
       2     m1();//最终抛给了JVM  JVM终止程序
       3     //一般main方法中的异常建议使用try..catch进行捕捉。
       4 }
       5 private static void m1() throws FileNotFoundException{
       6     m2();//throws 后面可以有多个异常  使用  “,”  隔开
       7 }
       8 private static void m2() throws FileNotFoundException{
       9      m3();//调用者可以抛被调用者异常的父类或者就抛被调用者异常,其他不行
      10  }  
      11  
      12 private static void m3() throws FileNotFoundException{
      13       new FileInputStream("D:\aaa.txt");
      14        System.out.println("以上代码出异常,这里不会执行");
      15   }
    3. throw抛出单个具体异常对象(一般手动抛异常)

      1 //异常不仅仅虚拟机可以抛,我们自己也可以抛。我们可以在代码中使用throw关键字(注意不带s)来抛出某个具体的异常对象。很多情况下我们会手动抛出运行时异常
      2 throw new RuntimeException("程序出现了异常");
      3 //常常和自定义异常结合
    4. throw和throws区别

      1. throws用来声明一个方法可能会产生的异常或者异常类型,在方法体内不做任何处理,将异常往调用方抛

        1. 在方法声明后,跟上异常类型名,可以跟多个,异常名之间逗号隔开

        2. throws抛出的异常是一种可能性,不一定会发生

        3. throws抛出的可以是一个异常范围,也可以是具体的异常

      2. throw用来抛出单个具体异常对象

        1. 用在方法体内,跟的是异常对象名

        2. 只能抛出一个异常对象

        3. 抛出的异常在方法体内处理

        4. throw若是抛出了异常,则说明一定发生了

    异常对象的常用方法

    异常对象有两个非常重要的方法:

    1. 获取异常简单的描述信息:

      String msg = exception.getMessage();

    2. 打印异常追踪的堆栈信息:

      exception.printStackTrace();

    例如:

    1  public static void main(String[] args) {
    2      //new一个异常
    3      NullPointerException e = new NullPointerException("空指针异常");
    4      //new了一个异常  但是没抛出  所以下面的代码继续执行  不会中断程序
    5      String msg = e.getMessage();//获取异常的信息
    6      System.out.println(msg);//打印的就是  空指针异常
    7      e.printStackTrace();//打印异常堆栈信息  底层有一个专门的线程负责这个事情的
    8      //java后台打印异常堆栈追踪信息的时候,采用了异步线程的方式打印的。
    9  }

    注意:以后查看异常的追踪信息,从上往下一行一行看,但是需要注意的是:SUN写的代码就不用看了(看包名就知道是自己的还是SUN的。)。

    重写之后的方法不能比重写之前的方法抛出更多(更宽泛)的异常,可以更少。(争对编译时异常)

    finally

    出现异常时,finally块里的代码会执行,但是当退出JVM时,finally语句块也不会执行

    例如:

    1 public static void main(String[] args){
    2 try{
    3   System.out.println("try...");
    4   System.exit();
    5 }finally{
    6    System.out.println("finally...");
    7   }
    8 }

    finally面试题

     1 public static void main(String[] args) {
     2   int result = m();
     3   System.out.println(result); //返回的是100
     4 }
     5  6 public static int m(){
     7   int i = 100;
     8   try {
     9       // 这行代码出现在int i = 100;的下面,所以最终结果必须是返回100
    10       // return语句还必须保证是最后执行的。一旦执行,整个方法结束。
    11       return i;
    12   } finally {
    13       i++;//这行代码执行了
    14   }
    15 }
    16 17 //反编译底层源码
    18 public static int m(){
    19 int i = 100;
    20 int j = i;
    21 i++;
    22 return j;
    23 }
    24 /**
    25 JVM规范里面明确说明了这种情况:
    26 大意就是如果在try中return的情况下,先把try中将要return的值先存到一个本地变量中,即本例中的i=100将会被保存下来。接下来去执行finally语句,最后返回的是存在本地变量中的值,即返i=100.
    27 28 还有一点要注意的,如果你在finally里也用了return语句,比如return ++i。那么程序返回值会是101。因为规范规定了,当try和finally里都有return时,会忽略try的return,而使用finally的return。
    29 */
    30 //总结:1、try中有return, 会先将值暂存,无论finally语句中对该值做什么处理,最终返回的都是try语句中的暂存值。  2、当try与finally语句中均有return语句,会忽略try中return。

    Java语句中的规则:

    1. 方法体中的代码必须遵循自上而下顺序依次逐行执行(亘古不变的语法!)

    2. return语句一旦执行,整个方法必须结束(亘古不变的语法!)

    底层这两条规则都遵循了

  • 相关阅读:
    118.Java_前定义
    117.数据结构概述(定义,基本术语,层次)
    116.C语言_文件
    115.C语言_函数
    java数组
    sql语句学习(第二季
    linux查看内存
    增强型for和Iterator学习
    ArrayList和LinkedList
    java并发回答
  • 原文地址:https://www.cnblogs.com/thesky-wfei/p/14124863.html
Copyright © 2020-2023  润新知