当前位置: 首页 > news >正文

第十章、 异常Exception

第十章、 异常Exception

10.1 异常的概念

  1. 引出异常:
    (1). 运行下面代码,看看有什么问题---->引出异常处理和异常处理机制
package chapter10.exception_;/*** @aim java基础学习* @note java笔记*/
public class Exception01 {public static void main(String[] args) {int num1=10;int num2=0;//当除数为0时,就会抛出异常:ArithmeticException,当抛出异常后,程序就退出了,不再执行下面的代码了//问题来了:当一个程序很大的时候,只是出现了一点小bug,不影响整个程序运行的时候,如果因为这个小bug而停止了整个程序运行//是不划算的,所以就提出来异常处理解决这个问题int res=num1/num2;System.out.println("程序正常运行.....");}
}

(2). 对异常进行捕获,保证程序可以正常运行
将可能会出现的代码块–>选中–>快捷键ctrl+alt+t–>选中try-catch/直接按6

package chapter10.exception_;/*** @aim java基础学习* @note java笔记*/
public class Exception01 {public static void main(String[] args) {int num1=10;int num2=0;//当除数为0时,就会抛出异常:ArithmeticException,当抛出异常后,程序就退出了,不再执行下面的代码了//问题来了:当一个程序很大的时候,只是出现了一点小bug,不影响整个程序运行的时候,如果因为这个小bug而停止了整个程序运行//是不划算的,所以就提出来异常处理解决这个问题try {int res=num1/num2;} catch (Exception e) {e.printStackTrace();//抛出异常System.out.println(e.getMessage());//输出异常信息}System.out.println("程序正常运行.....");}
}
/*
/ by zero
程序正常运行.....
*/
  1. 异常基本介绍
    (1). 基本概念
    Java语言中,将程序执行中发送不正常的情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)
    (2). 执行过程中所发送的异常事件可分为两类
    ① Error(错误):Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。如比:StackOverflowError[栈溢出]和OOM(out of memory内存不足),Error是严重错误,程序就崩溃。
    ② Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。比如空指针访问,试图读取不存在的文件,网络连接中断等等,Exception分为两大类:运行时异常[程序运行时,发送的异常]和编译时异常[编程时,编译器检测出的异常]

10.2 异常体系图(重点)

  1. 异常体系图,体系了继承和实现关系(简易版)
    在IDEA中输入关键字Throwable后,ctr+b查看源码,然后直接右键->图表->显示图表。
    选中Throwable,ctrl+alt+b可以添加子类或者右键显示实现就可以添加;ctrl+alt+b后直接按字母进行搜索即可出现搜索框。
    在这里插入图片描述

  2. 异常体系图(完整版)

在这里插入图片描述
在这里插入图片描述

  1. 异常体系图的小结
    (1). 异常分为两大类,运行时异常和编译时异常
    (2). 运行时异常(编译器检测不出来),编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该避免其出现的异常。Java.lang.RuntimeException类及它的子类都是运行时异常。
    (3). 对于运行时异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率可以产生影响。
    (4). 编译时异常,是编译器要求必须处置的异常。比如:读取文件时,文件不存在,这就是编译器异常,必须处理才可执行。

10.3 常见的异常

  1. 常见的运行时异常
    (1). NullPointerException空指针异常
    (2). ArithmeticException数字运算异常
    (3). ArrayIndexOutOfBoundsException数组下标越界异常
    (4). ClassCastException类型转换异常
    (5). NumberFormatException数字格式不正常异常[]

(1). NullPointerException空指针异常
当应用程序试图在需要对象的地方使用null时,抛出异常。

package chapter10.exception_;/*** @aim java基础学习* @note java笔记*/
public class NullPointerException_ {public static void main(String[] args) {String string=null;System.out.println(string.length());}
}
/*
Exception in thread "main" java.lang.NullPointerExceptionat chapter10.exception_.NullPointerException_.main(NullPointerException_.java:10)*/

(2). ArithmeticException数字运算异常
当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。

(3). ArrayIndexOutOfBoundsException数组下标越界异常
用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。

package chapter10.exception_;/*** @aim java基础学习* @note java笔记*/
public class ArrayIndexOutOfBoundsException_ {public static void main(String[] args) {int[] arr={1,2,3,4};for (int i = 0; i <= arr.length; i++) {System.out.println(arr[i]);}}
}
/*
1
2
3
4
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4at chapter10.exception_.ArrayIndexOutOfBoundsException_.main(ArrayIndexOutOfBoundsException_.java:11)*/

(4). ClassCastException类型转换异常
当试图将对象强制转换为不是实例的子类时,抛出该异常。例如,一下代码将生成一个ClassCastException异常。

package chapter10.exception_;/*** @aim java基础学习* @note java笔记*/
public class lassCastException_ {public static void main(String[] args) {A a=new B();//向上转型B b=(B)a;//向下转型C c=(C)a;//}
}class A{}
class B extends A{}
class C extends A{}
/*
Exception in thread "main" java.lang.ClassCastException: class chapter10.exception_.B cannot be cast to class
chapter10.exception_.C (chapter10.exception_.B and chapter10.exception_.C are in unnamed module of loader 'app')at chapter10.exception_.lassCastException_.main(lassCastException_.java:11)*/

(5). NumberFormatException数字格式不正常异常[]
当应用程序试图将字符串转成一种数值类型,但该字符串不能转换为设当格式时,抛出该异常=> 使用异常我们可以确保输入是满足条件数字。

package chapter10.exception_;/*** @aim java基础学习* @note java笔记*/
public class NumberFormatException_ {public static void main(String[] args) {String name="hello";int num=Integer.parseInt(name);}
}
/*
Exception in thread "main" java.lang.NumberFormatException: For input string: "hello"at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)at java.base/java.lang.Integer.parseInt(Integer.java:652)at java.base/java.lang.Integer.parseInt(Integer.java:770)at chapter10.exception_.NumberFormatException_.main(NumberFormatException_.java:10)*/
  1. 常见的编译异常
    编译异常是指在编译期间,就必须处理的异常,否则代码不能通过编译。
    (1). SQLException 操作数据库时,查询表可能发生异常
    (2). IOException 操作文件时,发生的异常
    (3). FileNotFoundException 当操作一个不存在的文件时,发生异常
    (4). ClassNotFoundException 加载类,而该类不存在时,发生异常
    (5). EOFException 操作文件,到文件末尾,发生异常
    (6). IllegalArgumentException 参数异常

  2. 判断下面代码是否正确,为什么?

在这里插入图片描述

10.4 异常处理概念

  1. 基本介绍
    异常处理就是当异常发生时,对异常处理的方式。

  2. 异常处理的方式
    (1). try-catch-finally
    程序员在代码中捕获发生的异常,自行处理
    (2). throws
    将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者就是JVM。

  3. try-catch-finally处理机制
    在这里插入图片描述

  4. throws处理机制

在这里插入图片描述

10.5 异常处理分类

10.5.1 try-catch方式处理异常

java提供try和catch块来处理异常。try块用于包含可能会出现错误的代码。Catch块用于处理try块中发生的异常。可以根据需要再程序中有多个数量的try…catch块。

  1. 基本语法
try{//可疑代码//将异常生成对应的异常对象,传递给catch块
}catch (异常){//对异常的处理
}
//如果没有finally,语法是可以通过的
  1. try-catch方式处理异常-注意事项
    (1). 如果异常发生了,则异常发生后面的代码不会执行,直接进入到代码块。
    (2). 如果异常没有发生,则顺序执行try的代码块,不会进入到catch。
    (3). 如果不希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等),在后面加上finally{}。
try{//可疑代码//将异常生成对应的异常对象,传递给catch块
}catch (异常){//对异常的处理
}finally {//释放资源等..
}

如下代码,例子:TryCatchDetail01

package chapter10.try_;import java.util.Scanner;/*** @aim java基础学习* @note java笔记*/
public class TryCatchDetail01 {public static void main(String[] args) {Scanner scanner=new Scanner(System.in);String str=scanner.next();try {int a=Integer.parseInt(str);//将输入的字符串类型的数字转换为整数类型System.out.println("数字:"+a);//如果输入不是整数,这句话就不会执行} catch (NumberFormatException e) {System.out.println("异常信息:"+e.getMessage());}finally {scanner.close();//不论是否发生异常都关闭资源}}
}
/*
输入:123
数字:123
输入:fa1
异常信息:For input string: "fa1"*/

(4). 可以有多个catch语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(Exception在后,NullPointerException在前),如果发生异常,只会匹配一个catch。

try {
}catch (NullPointerException){
}catch (Exception){
}finally {
}

例子TryCatchDetail02

package chapter10.try_;/*** @aim java基础学习* @note java笔记*/
public class TryCatchDetail02 {public static void main(String[] args) {try {Person person = new Person();
//            person=null;//NullPointerExceptionperson.say();int i=10/0;//ArithmeticException//要求子类异常要写在父类异常前面,不然会报错} catch (NullPointerException e){System.out.println("空指针异常"+e.getMessage());} catch (Exception e) {System.out.println("算术异常"+e.getMessage());}finally {//这里可以没有System.out.println("有没有异常都执行....");}}
}class Person{public void say(){}
}
/*
算术异常/ by zero
有没有异常都执行....*/

(5). 可以进行try-finally配合使用,这种用法相等于没有捕获异常,因此程序会直接崩掉。应用场景,就是执行一端代码,不管是否发生异常,都必须执行某个业务逻辑。

try{//代码
}final {//总是执行
}

例子:TryCatchDetail03

package chapter10.try_;/*** @aim java基础学习* @note java笔记*/
public class TryCatchDetail03 {public static void main(String[] args) {try {int n1=10;int n2=0;System.out.println(n1/n2);} finally {System.out.println("执行了finally...");}System.out.println("程序继续执行...");}
}
/*
执行了finally...
Exception in thread "main" java.lang.ArithmeticException: / by zeroat chapter10.try_.TryCatchDetail03.main(TryCatchDetail03.java:12)*/
  1. 练习
    (1). 判断下面代码输出是什么?
package chapter10.try_;/*** @aim java基础学习* @note java笔记*/
public class TryCatchExercise01 {public static void main(String[] args) {System.out.println(method());//4}public static int method(){try {String[] strings=new String[3];if(strings[1].equals("mark")){//NullPointerExceptionSystem.out.println(strings[1]);}else {strings[3]="smith";}return 1;} catch (NullPointerException e) {return 2;}catch (ArrayIndexOutOfBoundsException e){return 3;}finally {return 4;}}
}

(2). 判断下面代码输出是什么?

package chapter10.try_;/*** @aim java基础学习* @note java笔记*/
public class TryCatchExercise02 {public static void main(String[] args) {System.out.println(method());//4}public static int method(){int i=1;i++;try {String[] strings=new String[3];if(strings[1].equals("mark")){//NullPointerExceptionSystem.out.println(strings[1]);}else {strings[3]="smith";}return 1;} catch (ArrayIndexOutOfBoundsException e) {return 2;}catch (NullPointerException e){return ++i;}finally {//必须执行return ++i;}}
}

(3). 判断下面代码输出是什么?

package chapter10.try_;/*** @aim java基础学习* @note java笔记*/
public class TryCatchExercise03 {public static void main(String[] args) {System.out.println(method());//i=4//3}public static int method(){int i=1;i++;try {String[] strings=new String[3];if(strings[1].equals("mark")){//NullPointerExceptionSystem.out.println(strings[1]);}else {strings[3]="smith";}return 1;} catch (ArrayIndexOutOfBoundsException e) {return 2;}catch (NullPointerException e){return ++i;//i=3=>保存临时变量temp=3}finally {//必须执行++i;//4System.out.println("i="+i);}}
}

(4). 如果用户输入的不是一个整数,就提示他反复输入,知道输入一个整数为止。(用异常来做)。(肯定要循环的,不然try块 和catch块不管有没有问题,都只会执行一次)

package chapter10.try_;import java.util.InputMismatchException;
import java.util.Scanner;/*** @aim java基础学习* @note java笔记*/
public class TryCatchExercise04 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int input = 0;boolean validInput = false;while (!validInput) {try {System.out.print("请输入一个整数: ");input = scanner.nextInt();validInput = true; // 如果能成功获取整数则退出循环} catch (InputMismatchException e) {System.out.println("对不起,你输入的不是整数,请重新输入~~~~");scanner.nextLine(); // 清除缓冲区的非整数输入}}System.out.println("你输入的整数是: " + input);scanner.close();}
}
/*
请输入一个整数: 123f
对不起,你输入的不是整数,请重新输入~~~~
请输入一个整数: fa
对不起,你输入的不是整数,请重新输入~~~~
请输入一个整数: 12
你输入的整数是: 12*/
  1. try-catch-finally执行顺序小结
    (1). 如果没有出现异常,则执行try块中所有语句,不执行catch块中语句,如果有finally,最后还需执行finally里面的语句。
    (2). 如果出现异常,则try块中异常发生后,try块剩下的语句不再执行,将执行catch块中的语句,如果有finally,最后还需执行finally里面的语句。

10.5.2 Throws异常处理

  1. 基本介绍
    (1). 如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如果处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
    (2). 在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。
package chapter10.throws_;import java.io.FileInputStream;
import java.io.FileNotFoundException;/*** @aim java基础学习* @note java笔记*/
public class Throws01 {public static void main(String[] args) {}public void f2() throws FileNotFoundException {//1. 这里的异常是一个FileNotFoundException,属于编译异常 //2. 这里可以使用try-catch-finally//3. 也可以使用throws,抛出异常,让调用f2方法的调用者(方法)处理//4. throws后面的异常类型可以是具体产生的异常,也可以是父类异常//5. throws后面可以写多个异常,用逗号分隔。即异常列表。若父类异常都是一样的可以用父类异常替代FileInputStream fis=new FileInputStream("D://a.test");}
}
  1. throws注意事项和使用细节
    (1). 对应编译异常,程序中必须处理,比如:try-catch-或者throws。
    (2). 对于运行时异常,程序中如果没有处理,默认就是throws的方式处理
    (3). 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常类型的子类型。
    (4). 在throws过程中,如果有方法try-catch,相当于处理异常,就可以不必throws。
package chapter10.throws_;import java.io.FileNotFoundException;/*** @aim java基础学习* @note java笔记*/
public class ThrowsDetail {public static void main(String[] args) {}public void f1(){//1.这里调用f2()会报错,因为f2抛出了一个编译异常//2.f1作为f2的调用者,必须处理这个编译异常//3.要么使用try-catch-finally处理,或者继续throws 这个编译异常f2();}public void f2() throws FileNotFoundException {}public void f3(){//1.这里调用f4()不会报错,因为f4抛出了一个运行异常//2.在Java中,并不要求程序员显示处理运行异常,因为有默认处理机制f4();}public void f4() throws ArithmeticException{}}class Father{public void method() throws RuntimeException{}
}
class Son extends Father{//(3). 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,// 所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常类型的子类型。@Overridepublic void method() throws NullPointerException{}
}

10.6 自定义异常

  1. 基本概念
    当程序中出现了某些“错误”,但该错误信息并没有在Throwable子类中描述处理,这个时候可以自己设计异常类,用于描述该错误信息。

  2. 自定义异常的步骤
    (1). 定义类:自定义异常类名(程序员自己写)继承Exception或RuntimeException
    (2). 如果继承Exception,属于编译异常
    (3). 如果继承RuntimeException,属于运行异常(一般来说,继承RuntimeException)

  3. 自定义异常的应用案例CustomException.java
    当接收Person对象年龄时,要求范围在18-120之间,否则抛出一个自定义异常(要求 继承RuntimeException),并给出提示信息。

package chapter10.customexception_;/*** @aim java基础学习* @note java笔记*/
public class CustomException01 {public static void main(String[] args) {int age=12;if(!(age>=18 && age<=120)){throw new AgeException("年龄需要在18-120之间");}System.out.println("你的年龄范围正确");}
}//1.一般情况下,都是自定义异常是继承RuntimeException
//2.即把自定义异常做成 运行时异常,好处是,可以使用默认的处理机制(比较方便)
class AgeException extends RuntimeException{public AgeException(String message) {super(message);}
}
/*
Exception in thread "main" chapter10.customexception_.AgeException: 年龄需要在18-120之间at chapter10.customexception_.CustomException01.main(CustomException01.java:11)*/

10.7 throw和throws的对比

  1. throw和throws的区别
意义位置后面跟的东西
throws异常处理的一种方式方法声明处异常类型
throws手动生成异常对象的关键字方法体中异常对象
package chapter10.customexception_;/*** @aim java基础学习* @note java笔记*/
public class ThrowException {public static void main(String[] args) {try {methodA();} catch (Exception e) {System.out.println(e.getMessage());}methodB();}/*1.首先调用methodA方法,进入catch块:输出进入方法A,抛出异常给对象e,再进入finally块:输出用A方法的finally,最后main方法的e.getMessage()2.调用methodB方法,进入catch块:输出进入方法B,再进入finally块:输出调用B方法的finally3.输出如下:进入方法A用A方法的finally制造异常进入方法B调用B方法的finally*/static void methodA(){try {System.out.println("进入方法A");throw new RuntimeException("制造异常");} finally {System.out.println("用A方法的finally");}}static void methodB(){try {System.out.println("进入方法B");//4return;} finally {System.out.println("调用B方法的finally");//5}}
}

10.8 本章作业

  1. 编程题
    (1). 编写应用程序EcmDef.java,接收命令行的两个参数(整数),计算两数相除。
    (2). 计算两个数相除,要求使用方法cal(int n1,int n2)
    (3). 对数据格式不正确,缺少命令行参数、除0进行异常处理。
    解析:什么是命令行参数?其实就是args的参数。前面讲过怎么过去args参数。
    在这里插入图片描述
package chapter10.task_;import java.util.InputMismatchException;
import java.util.Scanner;/*** @aim java基础学习* @note java笔记*/
public class Task01 {public static void main(String[] args) {try {// 检查是否提供了足够的命令行参数if (args.length != 2) {throw new IllegalArgumentException("需要输入两个整数作为命令行参数");}// 将命令行参数转换为整数int n1 = Integer.parseInt(args[0]);int n2 = Integer.parseInt(args[1]);// 计算并输出结果double result = cal(n1, n2);System.out.println("两数相除的结果是:" + result);} catch (NumberFormatException e) {System.out.println("输入的参数格式不正确,请输入整数。");} catch (IllegalArgumentException e) {System.out.println(e.getMessage());} catch (ArithmeticException e) {System.out.println("除数不能为零。");}}public static double cal(int n1, int n2) {if (n2 == 0) {throw new ArithmeticException("除数不能为零。");}return (double) n1 / n2;}
}
//输出:两数相除的结果是:2.0
  1. 判断下面代码是否会发生异常,如果会,是哪种异常?如果不会,则打印结果是什么?
package chapter10.task_;/*** @aim java基础学习* @note java笔记*/
public class Task02 {public static void main(String[] args) {if(args[4].equals("john")){//可能发生NullPointerExceptionSystem.out.println("hello");}else{System.out.println("hi");}Object obj=args[2];Integer i =(Integer) obj;//一定会发生ClassCasException}
}
  1. 写出下面代码输出结果
package chapter10.task_;/*** @aim java基础学习* @note java笔记*/
public class Task03 {public static void main(String[] args) {try {func();System.out.println("a");} catch (Exception e) {System.out.println("c");//2}System.out.println("d");//3}public static void func(){try {throw new RuntimeException();}finally {System.out.println("b");//1}}
}
  1. 写出下面代码输出结果
package chapter10.task_;/*** @aim java基础学习* @note java笔记*/
public class Task04 {public static void main(String[] args) {try {showExce();System.out.println("a");} catch (Exception e) {System.out.println("b");//1} finally {System.out.println("c");//2}System.out.println("d");//3}public static void showExce() throws Exception{throw new Exception();}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 东土科技车规级网络芯片获批量应用
  • leetcode300. 最长递增子序列,动态规划附状态转移方程
  • Android 让程序随系统自动启动并允许后台运行(白名单)
  • arch linux 安装Budgie桌面
  • MySQL约束
  • 一、软件工程概述
  • 网络协议十 应用层 SPDY / HTTP2 / QUIC / HTTP3
  • 使用mybatis注解和xml映射执行javaWeb中增删改查等操作
  • Day18 Linux系统编程学习--文件
  • Java 中的面向对象编程 (OOP) 概念
  • 解析Java中1000个常用类:ListResourceBundle类,你学会了吗?
  • Linux安全与高级应用(十三)深入解析Linux中的rsync远程同步:原理、配置与应用
  • Layui——隐藏表单项后不再进行验证
  • 低代码开发平台:技术概览、效率与质量的权衡及挑战与机遇
  • Vue3配置路由
  • .pyc 想到的一些问题
  • [译]如何构建服务器端web组件,为何要构建?
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 2018一半小结一波
  • Angular 响应式表单 基础例子
  • es6--symbol
  • Git的一些常用操作
  • Git同步原始仓库到Fork仓库中
  • IOS评论框不贴底(ios12新bug)
  • JDK9: 集成 Jshell 和 Maven 项目.
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • 动态魔术使用DBMS_SQL
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 看域名解析域名安全对SEO的影响
  • 使用API自动生成工具优化前端工作流
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • ​configparser --- 配置文件解析器​
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ​如何在iOS手机上查看应用日志
  • ​水经微图Web1.5.0版即将上线
  • #pragma multi_compile #pragma shader_feature
  • $(this) 和 this 关键字在 jQuery 中有何不同?
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (1) caustics\
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (floyd+补集) poj 3275
  • (Oracle)SQL优化技巧(一):分页查询
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (二)测试工具
  • (篇九)MySQL常用内置函数
  • (太强大了) - Linux 性能监控、测试、优化工具
  • .NET 8.0 中有哪些新的变化?
  • .NET C# 使用 iText 生成PDF
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET delegate 委托 、 Event 事件