运行时异常和编译异常

运行时异常和编译异常解释异常中的编译异常以及运行时异常 并介绍异常处理方式

1.概念:

Java中将程序执行中发生的不正常情况称为异常(Exception)


2.分类

  • Error(错误):JVM无法解决的严重问题,程序会崩溃,比如JVM系统内部错误、资源耗尽等
  • Exception:因编程错误等外在因素导致的一般性问题,可以使用针对性代码进行处理,如空指针访问、网络连接中断等,Exception可以分为两大类:
    • 运行时异常:编译器检测不出,是java.lang.RuntimeException类及其子类,一般是指编程时的逻辑错误,可以不作处理(不做处理不是说不会报错),若全部处理可能会影响代码的可读性和运行效率
    • 编译时异常:编译器要求必须处置的异常,否则代码不能通过编译
  • 异常体系图:

在这里插入图片描述


3.常见运行时异常

  • NullPointerException:空指针异常,当应用程序试图在需要对象的地方出现null时抛出该异常
  • ArithmeticException: 数学运算异常,当出现异常的运算条件时抛出此异常
  • ArrayIndexOutOfBoundsException: 数组下标越界异常,用非法索引访问数组时抛出的异常
  • ClassCastException :类型转换异常,当试图将对象强制转换为不是实例的子类时抛出该异常
  • NumberFormatException:数字格式不正确异常,当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时抛出该异常

4.常见编译异常

  • SQLException:操作数据库时查询表可能发生的异常
  • IOException:操作文件时发生的异常
  • FileNotFoundException:操作不存在文件时发生的异常
  • ClassNotFoundException:加载类而类不存在时发生的异常
  • EOFException:操作文件到文件末尾发生异常
  • IllegalArguementException:参数异常

5.异常处理

  • 概念:当异常发生时对异常处理的方式
  • 处理方式:
    • try-catch-finally:程序员在代码中捕获发生的异常并自行处理
      try { 
                   // 可能有异常的代码 }catch (Exception e){ 
                   // 1.异常发生时将异常封装为Exception e传递给catch // 2.得到该对象后程序员自己处理 // 3.如果没有发生异常catch代码块不执行 }finally { 
                   // 不管try代码块是否发生异常都要执行finall代码块 // 一般用于释放资源 // 可以只有try-catch部分 } 
      • 异常发生后,异常部分后面的代码不会执行(不是必须将try代码块全部执行,而是try代码块中发生异常后面的代码不会执行)而是直接进入到catch代码块,注意try-catch代码块后面的代码还是会执行(除非未正确捕获或者在catch代码块中return了):
      try { 
                   String str = "psj"; int a = Integer.parseInt(str); System.out.println(a); // 该行代码不会执行 } catch (NumberFormatException e) { 
                   e.printStackTrace(); } System.out.println("程序继续..."); // 这一行代码还是会执行 
      • 可以有多个catch语句,但是父类异常在后,子类异常在前。如果发生异常只会匹配一个catch:
      try { 
                   String str = "psj"; int a = Integer.parseInt(str); System.out.println(a); } catch (NumberFormatException e) { 
                   e.printStackTrace(); // 执行该代码块 } catch (Exception e) { 
                   e.printStackTrace(); // 不会再去执行该代码块 } 
      • try-finally配合使用相当于没有捕获异常,所以如果出现异常会抛出异常,并没有自己处理,然后执行finally代码块

    • throws:如果方法可能发生某种异常但是无法确定如何处理该异常,可以将发生的异常抛出并交给方法的调用者处理,最顶级的处理者为JVM:
      public static void test() throws FileNotFoundException { 
                   FileInputStream f = new FileInputStream("psj.txt"); } 
      • throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类
      • throws后面可以是一个异常列表
      • try-catch-finallythrows二选一
      • 程序员没有显示处理异常,默认使用throws抛出异常

    在这里插入图片描述

  • 注意事项:
    • 编译异常必须处理,即显示使用throwstry-catch
    • 对于运行时异常,如果程序没有处理默认是throws方式处理
    • 子类重写父类方法时,抛出的异常类型要么和父类抛出的一致,要么为父类抛出异常类型的子类
  • 自定义异常:程序中的错误信息没有出现在Throwable子类中描述处理,此时需要自己设计异常类用于描述该错误信息
    • 定义类:异常类继承ExceptionRuntimeException(继承Exception属于编译异常,继承RuntimeException属于运行异常),一般继承RuntimeException(因为编译异常必须要处理)
    int age = 180; //要求范围在 18 – 120 之间,否则抛出一个自定义异常 if(!(age >= 18 && age <= 120)) { 
               //通过构造器设置信息 throw new AgeException("年龄需要在 18~120 之间"); } System.out.println("你的年龄范围正确."); //-----------自定义异常类------------ class AgeException extends RuntimeException{ 
               public AgeException(String message) { 
               System.out.println(message); } } 
  • throw和throws的区别:
意义 位置 后面跟的东西
throws 异常处理的一种方式 方法声明处 异常类型
throw 手动生成异常对象的关键字 方法体中 异常对象
try { 
         if (args.length != 4){ 
         // 该行代码生成一个异常,因为try代码块中出现异常,所以又去执行catch代码块 throw new ArrayIndexOutOfBoundsException("参数个数不对"); } } catch (ArrayIndexOutOfBoundsException e) { 
         System.out.println(e.getMessage()); } 

tips:

  • 为什么try-catch-finally外的代码还可以执行?因为使用异常捕获的目的就是为了让程序继续正常执行(但是出现异常时try中的代码不能再继续往下执行)
  • 既然try-catch外的代码块在出现异常后依旧可以执行,为什么还需要finally代码块?因为catch并不能保证一定能捕获到正确的异常,会导致后续代码无法执行:
try { 
         String str = "psj"; int a = Integer.parseInt(str); System.out.println(a); } catch (ArrayIndexOutOfBoundsException e) { 
         // 异常捕获错误,这里是类型转换异常却捕获的是数组越界 e.printStackTrace(); } System.out.println("程序继续..."); 
  • try/catch代码块中如果有return语句,还是会去执行finally代码块,如果finally中有return语句就执行finally的return语句,没有就执行try/catch代码块中的return语句(假设try-catch-finally中try-catch中都有return语句,不出现异常时执行try中的,出现异常就执行catch中的)
System.out.println("执行test方法后,i=" + test()); //--------------test方法-------------- public static int test() { 
         int i = 0; try { 
         String str = "psj"; int a = Integer.parseInt(str); return i; } catch (NumberFormatException e) { 
         return ++i; // 执行++i后i=1,但是不会执行return,而是必须执行finally代码块 } finally { 
         ++i; // 这个i是上面++i后的i值,所以该步++i后变为2 System.out.println("执行finally代码块后,i=" + i); return 3 } } // 最后结果: 执行finally代码块后,i=2 执行test方法后,i=3 
  • 由于声明代码块中的变量为局部变量,所以声明在try中的变量不能在catch和finally中使用,反之亦然(比如在JDBC中会把需要关闭的对象在try-catch-finally代码块外先声明并赋值null)
  • finally代码块中有return语句了就不能再在try-catch-finally外加上return语句,因为finally代码块中的return语句是必须执行的。如果有try-catch中都有return语句,此时也不能在try-catch-finally外加上return语句

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232742.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • xcode armv6 armv7 armv7s arm64

    目前ios的指令集有以下几种:armv6iPhoneiPhone2iPhone3G第一代和第二代iPodToucharmv7iPhone4iPhone4Sarmv7siPhone5iPhone5Carm64iPhone5S 机器对指令集的支持是向下兼容的,因此armv7的指令集是可

    2022年4月7日
    43
  • Expand命令_copy命令的用法

    Expand命令_copy命令的用法使用Expand命令行可以在计算机没有安装Windows操作系统的情况下应用批处理文件和脚本:虽然有多个基于Windows的工具可以压缩和解压缩文件(包括WinZip和WinRAR),但是必须有一个可以工作的Windows操作系统才能使用它们。Expand工具用来压缩的WndowsCAB文件中展开文件,并把释放出来的文件保存在磁盘的指定目录内。这个工具通常用来从Windows安装

    2025年6月11日
    3
  • G1垃圾收集器详解

    G1垃圾收集器详解G1垃圾收集器GC收集器的三个考量指标:占用的内存(Capacity)延迟(Latency)吞吐量(Throughput)随着硬件的成本越来越低,机器的内存也越来越大,GC收集器占用的内存基本上可以容忍。而吞吐量可以通过集群(增加机器)来解决。随着JVM中内存的增大,STW的时间成为JVM急迫解决的问题,如果还是按照传统的分代模型,使用传统的垃圾收集器,那么STW的时间将会越来越长。在传统的垃圾收集器中,STW的时间是无法预测的,有没有一种办法,能够首先定义一个停顿时间,然后反向推算收集内

    2022年5月1日
    48
  • 原生js数组排序

    原生js数组排序原生js数组排序js排序以正序为例(即由小到大)vararr=[0,2,1,4,3,9,6,5,7,8];//未排序的数组varsortArr=null;//排序后得到的数组1sort排序sortArr=arr.sort(function(a,b){ returna-b})sort是es3增加的数组方法,大家可以放心使用(支持到ie…

    2022年6月12日
    35
  • java的重载和重写实例_java中重写和重载的区别

    java的重载和重写实例_java中重写和重载的区别重写只存在于子类与父类中 重载存在于一个类中 具体区别如下 一 重写 override override 是重写 覆盖 了一个方法 以实现不同的功能 一般是用于子类在继承父类时 重写 重新实现 父类中的方法 重写 覆盖 的规则 1 重写方法的参数列表必须完全与被重写的方法的相同 否则不能称其为重写而是重载 2 重写方法的访问修饰符一定要大于被重写方法的访问修饰符 public gt protecte

    2025年10月23日
    3
  • JAVA String 截取字符串的方法(含 substring 索引截取示例)

    String.substring():用于返回一个字符串的子串用法如下:string.substring(from,to)其中from指代要抽去的子串第一个字符在原字符串中的位置to指代所要抽去的子字符串最后一个字符的后一位(这个参数可以不加)下面就对String.substring()做举例:1、string.substring(from):此时相当于从from位置截取到原字…

    2022年4月3日
    1.4K

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号