目录
一、异常基本介绍
Ⅰ 什么是异常(Exception)?
▷ 异常处理(又称为错误处理)是程序在运行时可能出现的会导致程序运行终止的错误。这种错误是不能通过编译系统检查出来的(开发过程中的语法错误和逻辑错误不是异常)。异常处理分离了接收和处理错误代码,也帮助增强了代码的可读性,方便了维护者的阅读和理解。它提供了处理程序运行时出现的任何意外或异常情况的方法。它使用 try、catch 和 finally 关键字来尝试可能未成功的操作,处理失败,以及在事后清理资源。
▷ 异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件)。通过异常处理,我们可以对用户在程序中的非法输入进行控制和提示,以防程序崩溃。从进程的视角,硬件中断相当于可恢复异常,虽然中断一般与程序流本身无关。从子程序编程者的视角,异常是很有用的一种机制,用于通知外界该子程序不能正常执行。如输入的数据无效(例如除数是0),或所需资源不可用(例如文件丢失)。如果系统没有异常机制,则编程者需要用返回值来标示发生了哪些错误。
Ⅱ 执行过程的两类异常事件
㈠ Error(错误):Java虚拟机无法解决的严重问题、错误,系统会崩溃。❶如:JVM系统内部出错、资源耗尽等严重问题。❷如:StackOverflowError[栈溢出] 和 OOM(内存耗尽)。
㈡ Exception:其他因编译错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。列如空指针访问,试图读取不存在的文件,网络连接中断等等。Exception
分为运行异常和编译异常两大类。
Ⅲ 异常体系图
Ⅳ 运行时异常和编译时异常
㈠ 运行时异常:编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该避免它出现的异常,(java.lang.RuntimeException 类及它的子类都是运行异常)。对于运行异常可以不做处理,也就是说,当程序中出现这类异常时,即使没有使用try…catch语句捕获或使用throws关键字声明抛出,程序也能编译通过。因为这类异常比较普遍,若完全处理可能会对程序的可读性和运行效率产生影响。运行时异常一般是由程序中的逻辑错误引起的,在程序运行时无法恢复。
㈡ 编译时异常:在Java中, Exception类中除了 RuntimeException类及其子类都是编译时异常。编译时异常的特点是Java编译器会对其进行检查,如果出现异常,编译器要求必须处理异常,否则程序无法通过编译。
二、常见运行异常
▶ 常见异常
▷
NullPointerException :空指针异常▷
ArithmeticException :数学运算异常▷
ArrayIndexOutOfBoundsException :数组下标越界异常▷
ClassCastException :类型转换异常▷
NumberFormatException :数字格式不正确异常[]
▶ 异常代码示例
1、NullPointerException:
String name = null; System.out.println(name.length()); //此处会抛出空指针异常
2、ArithmeticException :
int a = 2; int b = 0; int c = a / b;//此处会抛出数学运算异常,除数不能为0
3、ArrayIndexOutOfBoundsException :
int[] arr = {1,2,3}; for(int i = 0;i <= 3;i++){ //此处抛出数组越界异常 System.out.println(arr[i]); }
4、ClassCastException :
public class ClassCastException_ { public static void main(String[] args) { A b = new B(); //向上转型 B b2 = (B)b;//向下转型,这里是 OK C c2 = (C)b;//B类和C类不存在关系,不能转换,这里抛出 ClassCastException } } class A {} class B extends A {} class C extends A {}
5、NumberFormatException :
String name = "努力学习"; //将 String 转成 int int num = Integer.parseInt(name);//抛出 NumberFormatException
三、常见编译时异常
▶ 常见异常
关键字 功能解释 SQLException 操作数据库时,查询表可能发生的异常 IOException 操作文件时,发生的异常 FileNotFoundException 当操作一个不存在的文件时,发生的异常 ClassNotFoundException 加载类,而该类不存在时,发生的异常 EOFException 操作文件,到文件末尾,发生的异常 IllegalArguementException 参数异常 OException 输入输出时异常 DataFormatException 数据格式化异常 NoSuchFieldException 没有匹配的属性异常 NoSuchMethodException 没有匹配的方法异常 TimeoutException 执行超时异常
▶ FileNotFoundException 代码示例
package com.hspedu.exception_; import java.io.FileInputStream; import java.io.IOException; public class Exception02 { public static void main(String[] args) { try { FileInputStream fis; fis = new FileInputStream("d:\\aa.jpg"); int len; while ((len = fis.read()) != -1) { System.out.println(len); } fis.close(); } catch (IOException e) { e.printStackTrace(); } } }
四、异常处理机制
1、try-catch-finally 处理机制
(1)图示:
2、注意细节:
▷ 如果异常发生了,则异常发生后面的代码不会执行,直接进入到 catch 块▷ 如果异常没有发生,则顺序执行 try 的代码块,不会进入到 catch▷ 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用如下代码- finally▷ 如果 try 代码块有可能有多个异常▷ 可以使用多个 catch 分别捕获不同的异常,相应处理▷ 要求子类异常写在前面,父类异常写在后面▷ 可以进行 try-finally 配合使用, 这种用法相当于没有捕获异常,因此程序会直接崩掉/退出。应用场景:就是执行一段代码,不管是否发生异常, 都必须执行finally中的业务逻辑3、代码示例1:
int num1 = 10; int num2 = 0; try { int res = num1 / num2; } catch (Exception e) { System.out.println(e.getMessage()); }finally { System.out.println("finally 代码块被执行..."); }
4、代码示例2:
try { Person person = new Person(); person = null; System.out.println(person.getName());//NullPointerException int n1 = 10; int n2 = 0; int res = n1 / n2;//ArithmeticException } catch (NullPointerException e) { System.out.println(e.getMessage());//空指针异常,子类 } catch (ArithmeticException e) { System.out.println(e.getMessage()); //算数异常,子类 } catch (Exception e) { System.out.println(e.getMessage()); //全部异常,父类 } finally { System.out.println("finally 代码块被执行..."); }
2、throws 异常处理机制
1、图示
2、注意细节:
▷ 对于编译异常,程序中必须处理,比如 try-catch 或者 throws▷ 对于运行时异常,程序中如果没有处理,默认就是 throws 的方式处理▷ 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常类型的子类型▷ 在 throws 过程中,如果有方法 try-catch , 就相当于处理异常,就可以不必 throws3、代码示例1:public static void f1() throws FileNotFoundException { f2(); //想调用f2方法 //就得继续抛出编译异常或者用try-catch进行处理 } public static void f2() throws FileNotFoundException { //抛出编译异常 FileInputStream fis = new FileInputStream("d://aa.txt"); }
4、代码示例2:
public static void f4() { f5(); //f5方法抛出的是运行异常,所以可以不做处理 } public static void f5() throws ArithmeticException { //抛出运行异常 }
3、总结
五、自定义异常处理
1、基本介绍
Java本身已经提供了大量的异常类,但是这些异常类在实际的工作中往往并不够使用。例如,当要执行数据增加操作的时候,有可能会出现一些错误的数据,而这些错误的数据,一旦出现就应该抛出异常(如BombException 异常),但是这样的异常Java并没有,这时就需要由用户自己定义一个异常类。 要想实现自定义异常类,只需继承父类Exception (强制性异常处理)或RuntimeException (选择性异常处理)即可。
2、应用场景
◇ 使异常信息更加具体。比如,在跟别人合作开发时,程序出现了空指针异常,但别人可能不清楚这个空指针具体是如何产生的,这时即可自定义一个显示具体信息的异常,如自定义一个用户信息为空时抛出的异NullOfUserInfoException, 当这个异常发生时就代表用户填写的信息不完整。
◇ 程序中有些错误是符合Java 语法的,但不符合业务逻辑或者实际情况,如程序中现了一个人的年龄是负数、人员个数为小数等。
◇ 在分层的软件架构中,通常由表现层进行异常捕获和处理。
3、注意
◇ 一般情况下,我们自定义异常是继承 RuntimeException◇ 把自定义异常做成 运行时异常,好处是我们可以使用默认的处理机制4、代码示例:
static void avg (int age) throws MyException{ if (age < 0){//11判断方法中的参数是否满足指定条件 throw new MyException ("年龄不可以使用负数”); //自定义异常 } else System. out .println("王师傅今年”+ age + "岁了! "); }
六、异常使用注意事项
◆ 不要过度使用异常。虽然通过异常可以增强程序的健壮性,但同样,如果使用过多不必要的异常处理,则可能会影响程序的执行效率。
◆ 不要使用过于庞大的tr..catch 代码块。在一个try代码块中放置 大量的代码,这种写法看上去“很简单”,但是由于try代码块中的代码过于庞大,业务过于复杂,会造成try代码块中出现异常的可能性大大增加,从而导致分析异常原因的难度也大大增加。
◆ 避免使用catch(Exception e)。因为如果所有异常都采用相同的处理方式,则将导致无法对不同异常分情况处理。另外,这种捕获方式可能将程序中的全部错误、异常捕获到,这时如果出现一些“关键”异常,则可能会被“悄悄地”忽略掉。
◆ 不要忽略捕捉到的异常,遇到异常一定要 及时处理。
◆ 如果父类抛出多个异常,则覆盖方法必须抛出相同的异常或其异常的子类,不能抛出新异常。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/66217.html