Java基础43 异常(Exception)

news/2024/4/27 2:07:27/文章来源:https://blog.csdn.net/chenjiap/article/details/128960493

异常(Exception)

  • Exception
    • 1.1 异常的概念
    • 1.2 异常体系图(☆)
    • 1.3 异常处理分类
      • 1.3.1 运行时异常(☆)
      • 1.3.2 编译时异常(☆)
    • 1.4 异常处理(☆)
      • 1.4.1 try-catch异常处理
      • 1.4.2 throws异常处理
    • 1.5 自定义异常
    • 1.6 throw和throws的对比
    • 1.7 Exception练习


Exception

1.1 异常的概念

● 什么是异常?

异常就是程序中的一些错误。

● 异常发生的原因是什么?

异常发生的原因有很多,在Java语言中,将程序执行中发生的不正常情况称为 " 异常 " 。(开发过程中的语法错误和逻辑错误不是异常

● 程序执行过程中所发生的异常事件可分为两类

1)Error(错误):Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。

比如:StackOverflowError [ 栈溢出 ] 和 OOM(out of memory),Error是严重错误,程序会崩溃。

2)Exception(异常):其他因编程错误或偶然的外在因素导致的一般性问题,是可以使用针对性的代码进行处理。

例如空指针访问,视图读取不存在的文件,网络连接中断等等。

● 异常与错误的直白理解

你写了一段代码,但是你写的代码中有语法错误,少了一些标点符号,那么运行出来的结果就会是:

java.lang.Error;

这就是错误,而不是异常。

而如果你写的那段代码没有任何语法错误,但是你写的语句是用一个数除以一个0,而在java中会因为你用0做了除数,而出现异常,并给你红色的警告:

java.lang.ArithmeticException

这就是异常


1.2 异常体系图(☆)

● 异常体系图一览

图一:

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

在这里插入图片描述

(图片来源于韩老师的视频)


1.3 异常处理分类

  1. 异常分为两大类:运行时异常和编译时异常。
  2. 运行时异常:编译器不要求强制处置的异常。 一般是指编程时的逻辑错误,是程序员应该避免其出现的异常。【java.lang.RuntimeException类及它的子类都是运行时异常】
  3. 对于运行时异常,可以不做处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
  4. 编译时异常:是编译器要求必须处置的异常。

1.3.1 运行时异常(☆)

● 常见的运行时异常

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

1.3.2 编译时异常(☆)

编译异常是指在编译期间,就必须处理的异常,否则代码不能通过编译。

● 常见的编译异常

  1. SQLException (操作数据库时,查询表可能发生异常)
  2. IOException (操作文件时,发生的异常)
  3. FileNotFoundException (当操作一个不存在的文件时,发生异常)
  4. ClassNotFoundException (加载类,而该类不存在时,异常)
  5. EOFException (操作文件,到文件末尾,发生异常)
  6. IllegalArguementException (参数异常)

1.4 异常处理(☆)

异常处理就是当异常发生的时候,对异常处理的方式。

● 异常处理机制

1) try - catch - finally

程序员在代码中捕获发生的异常,自行处理。

2) throws

将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者是JVM。

注意:

  1. try - catch - finally 和 throws 必须二选一
  2. 如果程序没有显示处理异常,则默认是throws

方式一 (try - catch - finally)

try{代码/可能的异常
}catch(Exception e){捕获到异常,当异常发生时,系统将异常封装成Exception 对象 e,传递给catch,得到异常对象后,程序员自行处理注意:如果没有发生异常,catch代码块则不执行
}finally{不管try代码块是否有异常发生,始终要执行finally
}

方式二 (throws)

throws是会把异常返回给上一级,直到最后的JVM,JVM会输出异常信息,然后退出程序。

在这里插入图片描述

1.4.1 try-catch异常处理

● try - catch方式处理异常介绍

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

try - catch 语法

try {可疑代码将异常生成对应的异常对象,传递给catch}catch(异常){对异常的处理
}

● try-catch 注意事项

  1. 如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch块。(try块中发生异常后,try块剩下的语句不再执行)
  2. 如果异常没有发生,则顺序执行try的代码块,不会进入到catch。
  3. 如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等),则使用 - finally {}
  4. 可以有多个catch语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(Exception在后,NullPointerException在前),如果发生异常,只会匹配一个catch。
try{Person person = new Person();person.say();int i = 10/0;
} catch (NullPointerException e){System.out.println("here1");e.printStackTrace();
} catch (Exception e){System.out.println("here2");e.printStackTrace();
} finally {System.out.printl("here3");
}
  1. 可以进行 try - finally 配合使用,这种用法相当于没有捕获异常,因此程序会直接崩掉,应用场景:就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑。
try{//代码
} finally {//总是执行
}

1.4.2 throws异常处理

● 基本介绍

1) 如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理

2)在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。

● 使用演示

public class Throws01{public static void main(String[] args){}public void f2() throwsFileNoteFoundException	{//此处的FileNoteFoundException可以换成它的父类Exception//创建了一个文件流对象//1.这里的异常是一个FileNoteFoundException 编译异常//2.使用前面讲过的 try - catch - finally//3.使用throws,抛出异常,让调用f2方法的调用者(方法)处理//4.throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类//5.throws关键字也可以是异常列表,即可以抛出多个异常FileInputStream fis = new FileInputStream("d://aa.txt");}
}

● throws注意事项及其使用细节

  1. 对于编译异常,程序中必须处理,比如 try-catch 或者 throws。
  2. 对于运行时异常,程序中如果没有处理,默认就是throws的方式处理。
  3. 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型。
  4. 在throws过程中,如果有方法 try - catch,就相当于处理异常,就可以不必throws。

注意!!!

● 第一点

下面的代码,在f1()中调用 f3(),如果我解开f3的注释,就会出现红色的警告,原因是:

f3()抛出的是一个编译异常,即这时,就要f1()必须处理这个编译异常。

public static void f1(){//f3();
}public static void f3() throws FileNotFoundException{FileInputStream fis = new FileInputStream("d://aa.txt");
}

处理方法

在f1()中,要么 try - catch - finally,或者继续throws这个编译异常

选用throws方法处理

public static void f1() throws FileNotFoundException{f3();
}public static void f3() throws FileNotFoundException{FileInputStream fis = new FileInputStream("d://aa.txt");
}

● 第二点

下面的代码中在f4()中调用f5()并没有报错,原因是:

f5()抛出的是运行异常,而Java中,并不要求程序员显示处理运行异常,因为有默认处理机制。

public static void f4(){f5();
}public static void f5() throws AritmeticeException{
}

1.5 自定义异常

● 什么是自定义异常?

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

● 自定义异常的步骤

  1. 定义类:自定义异常类名(程序员自定)继承Exception 或 RuntimeException。
  2. 如果继承Exception,则属于编译异常
  3. 如果继承RuntimeException,则属于运行异常(一般来说都是继承RuntimeException)

● 自定义异常的应用实例

实例1

当我们接收Person对象年龄时,要求范围在18 - 120 之间,否则就抛出一个自定义异常(要求
继承RuntimeException),并给出提示信息。

代码实现

public class Test02 {public static void main(String[] args) {int age = 23;//要求范围在18 - 120 之间,否则就抛出一个自定义异常if(!(age >=18 && age <= 120)){//通过构造器设置年龄throw new ageException("年龄要求在18—120之间。");}System.out.println("输入的年龄范围正确。");}//自定义异常类static class ageException  extends RuntimeException{public ageException(String message) { //构造器super(message);}}
}

注意:

一般情况下,我们自定义异常是继承RuntimeException,即把自定义异常做成运行时异常,好处是:我们可以使用默认的处理机制,比较方便。


1.6 throw和throws的对比

意义位置后面跟的内容
throws异常处理的一种方式方法声明处异常类型
throw手动生成异常对象的关键字方法体中异常对象

throw使用实例

看下面的测试代码中输出什么内容?

ReturnExceptionDemo类

class ReturnExceptionDemo{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");return;	}finally{System.out.println("调用B方法的finally");	}}
}

main方法

public static void main(String[] args){try{ReturnExceptionDemo.methodA();}catch(Exception e){System.out.println(e.getMessage());}ReturnExceptionDemo.methodB();
}

答案

在这里插入图片描述

1.7 Exception练习

看看下面代码是否正确,为什么?

题一:

String friends[] = {"tom","jack","milan"};
for(int i = 0; i < 4; i++){System.out.println(friends[i]);
}

题二:

Cat c = new Cat();
cat = null;
System.out.println(cat.name);

题三:

public class AAA{int x;public static void main(){int y;AAA a = new AAA();y = 3 / a.x;System.out.println("program ends ok!");}
}

题四:

class Person{public static void main(String[] args){Object obj = new Date();Person person;person = (Person)obj;System.out.println(person);}
}

答案

题一:

ArrayIndexOutOfBoundsException (数组越界异常)

题二:

NullPointerException(空指针异常)

题三:

ArithmeticException (数学运算异常)

题四:

ClassCastException (类型转换异常)


● try - catch 异常处理练习

题一

以下代码输出什么?

public class Exception01{public static int method(){try{String[] names = new String[3];if(names[1].equals("tom")){System.out.println(names[1]);}else{names[3] = "coco";	}return 1;} catch (ArrayIndexOutOfBoundsException e){return 2;} catch (NullPointerException e){return 3;} finally {return 4;	}}public static void main(String[] args){System.out.println(method());}
}

分析

  1. 创建数组后并没有给数组添加值,所以数组所存的三个数据都为Null。
  2. 进入到if语句里,names[1]的值为Null,所以会有NullPointerException异常的错误信息报出。
  3. 当获取到NullPointerException时会进入return3的catch中。
  4. 但是注意:try - catch 的结构最后有一个finally,所以即使你捕获到了NullPointerException也必须要执行finally,所以最后的结果是return 4,输出的结果为:4。

结果

4


题二

public class Exception02{public static int method(){int i =1;try{i++;String[] names = new String[3];if(names[1].equals("tom")){System.out.println(names[1]);}else{names[3] = "coco";	}return 1;} catch (ArrayIndexOutOfBoundsException e){return 2;} catch (NullPointerException e){return ++i;} finally {return ++i;	}}public static void main(String[] args){System.out.println(method());}
}

分析

  1. int i = 1;
  2. 进入到try,i++(i=2),创建了数组后,并没有给数组赋值,所以数组依旧是三个Null。
  3. 进入到if,由于数组里是null,所以程序会报空指针异(NullPointerException)。
  4. 进入到catch里,传入NullPointerException e,由于有finally,所以return 不执行,但是 i 是先自增才输出,所以i就先变为了3,才继续下一步。
  5. 执行finally里的代码,return ++i;最后输出的结果为4。

答案

在这里插入图片描述


题三

public class Exception02{public static int method(){int i =1;try{i++;String[] names = new String[3];if(names[1].equals("tom")){System.out.println(names[1]);}else{names[3] = "coco";	}return 1;} catch (ArrayIndexOutOfBoundsException e){return 2;} catch (NullPointerException e){return ++i;} finally {++i;System.out.println("i="+ i);	}}public static void main(String[] args){System.out.println(method());}
}

分析

  1. i=1,程序进入try中,i++(i=2),由于创建数组时并没有给出数组的值,所以数组里3个位置都为Null。
  2. 进入if,由于三个位置的值都是Null,所以程序出现NullPointerException异常,进入到catch中。
  3. 进入到NullPointerException e 的catch中,++i(i=3),这里的 i 由一个临时变量temp存储起来,再进入到finally。
  4. 进入到finally中,++i(i=4),打印出:“i=4”,由于finally中只有输出语句,程序并没有结束,所以还会回到上一级的catch里。
  5. 回到NullPointerException的catch中,执行return ++i;(return temp)输出结果3。
  6. 所以最终得结果为:i=4,3。

答案

**答案**


● 本章练习

题一

  1. 编写应用程序EcmDef.java,接收命令行的两个参数(整数),计算两数相除。
  2. 计算两个数相除,要求使用方法cal(int n1,int n2)
  3. 对数据格式不正确(NumberformatException)、缺少命令行参数(ArrayIndexOutOfBoundsException)、除0进行异常处理(ArithmeticException)。

代码实现

public class Homework01{public static void main(String[] args){try{//验证输入的参数的个数是否正确(两个参数)if(args.length != 2){throw new ArrayIndexOutOfBoundsException("参数个数不对");	}//接收整数int n1 = Integer.parseInt(args[0]);int n2 = Integer.parseInt(args[1]);//该方法可能抛出ArithmeticExceptiondouble res = cal(n1,n2); System.out.println("计算结果是=" + res);} catch(ArrayIndexOutOfBoundsException e){System.out.println(e.getMessage());	} catch(NumberFormatException e){System.out.println("参数格式不正确,需输出整数");} catch(ArithmeticException e){System.out.println("出现了除0的异常");}}//cal方法,求两数商public static double cal(int n1,int n2){return n1/n2;}
}

题二

看看以下代码是否会发生异常,如果会,是哪种异常?如果不会,则打印结果是什么?

public static void main(String[] args){if(args[4].equals("jock")){ System.out.println("AA");}else{System.out.println("BB");}Object o = args[2]; Integer i = (Integer)o;
}

分析与答案

这里的args.length=0,因为没有给args一个值或者长度,所以会发生ArrayIndexOutOfBoundsException(数组越界异常)

if(args[4].equals("jock"))

String -> Object,发生了向上转型,所以不会异常

Object o = args[2]; 

这里会发生异常(ClassCastException),转型错误。

Integer i = (Integer)o;

题三

写出程序结果

public static void func(){try{throw new RuntimeException();}finally{System.out.println("B");}
}
public static void main(String[] args){try{func();System.out.println("A");} catch (Exception e){System.out.println("C");}System.out.println("D");}
}

答案

在这里插入图片描述


题四

写出程序结果

public static void main(){try{showExce();System.out.println("A");} catch(Exception e){System.out.println("B");} finally{System.out.println("C");}System.out.println("D");
}
public static void showExce() throws Exception{throw new Exception();
}

答案
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_72271.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Git】Git下载安装与使用(一)

目录 1. 前言 1.1 什么是Git 1.2 使用Git能做什么 2. Git概述 2.1 Git简介 2.2 Git下载与安装 3. Git代码托管服务 3.1 常用的Git代码托管服务 3.2 码云代码托管服务 1. 前言 1.1 什么是Git Git是一个分布式版本控制工具&#xff0c;主要用于管理开发过程中的源代码…

Cookies与Session会话技术详解

引言:日常生活中&#xff0c;人和人之间沟通交流&#xff0c;涉及到一个词----会话&#xff0c;软件中一样存在会话&#xff0c;如&#xff1a;网购登录&#xff0c;访问公司OA系统也是不断的会话&#xff0c;软件中如何管理浏览器客户端和服务端之间会话过程中的会话数据呢&am…

盘点四种自动化测试模型实例及优缺点

一&#xff0c;线性测试 1.概念&#xff1a; 通过录制或编写对应应用程序的操作步骤产生的线性脚本。单纯的来模拟用户完整的操作场景。 &#xff08;操作&#xff0c;重复操作&#xff0c;数据&#xff09;都混合在一起。 2.优点&#xff1a; 每个脚本相对独立&#xff0…

【java】java sftp传输 ,java smb传输访问共享文件夹 集成springboot

文章目录java的sftp传输sftp注意事项java smb传输smb注意事项tips: 集成springboot与不集成springboot区别不大&#xff0c;springboot中无非是引入一个maven依赖 加一个Component注解 &#xff0c; 默认是单例&#xff1b; 复制代码前 请先认真看注意事项 java的sftp传输 依赖…

网络安全态势感知研究综述

摘要&#xff1a;随着物联网、云计算和数字化的迅速发展&#xff0c;传统网络安全防护技术无法应对复杂的网络威胁。网络安全态势感知能够全面的对网络中各种活动进行辨识、理解和预测。首先分别对态势感知和网络安全态势感知的定义进行了归纳整理&#xff0c;介绍了网络安全态…

从0探索NLP——导航帖

从0探索NLP——导航帖 人工智能是一个定义宽泛、知识组成复杂的领域&#xff0c;而NLP是人工智能领域中的一类任务&#xff0c;他在哪呢&#xff1f;Emmmmm~不能说都有涉猎只能说全都都沾点&#xff1a; 每次想要针对NLP的某一点进行讲解时&#xff0c;不讲那写细枝末节&…

全链路压力测试

压力测试的目标&#xff1a; 探索线上系统流量承载极限&#xff0c;保障线上系统具备抗压能力 复制代码 如何做全链路压力测试&#xff1a; 全链路压力测试&#xff1a;整体步骤 容量洪峰 -》 容量评估 -》 问题发现 -》 容量规划 全链路压力测试&#xff1a;细化过程 整体目…

YOLOv6-3.0-目标检测论文解读

文章目录摘要算法2.1网络设计2.2Anchor辅助训练2.3自蒸馏实验消融实验结论论文&#xff1a; 《YOLOv6 v3.0: A Full-Scale Reloading 》github&#xff1a; https://github.com/meituan/YOLOv6上版本参考 YOLOv6摘要 YOLOv6 v3.0中YOLOv6-N达到37.5AP&#xff0c;1187FPS&…

linux下安装minio

获取 MinIO 下载 URL:访问&#xff1a;https://docs.min.io/ 一&#xff0c;进入/opt 目录&#xff0c;创建minio文件夹 cd /optmkdir minio二&#xff0c;wget下载安装包 wget https://dl.minio.io/server/minio/release/linux-amd64/minio三&#xff0c;进入minio文件夹创建…

如何使用 API 工具做 Websocket 测试

在 API 测试中&#xff0c;对 Websocket 协议的支持呼声越来越高&#xff0c;今天给大家推荐一款 开源的 API 管理工具——Postcat&#xff0c;以及教教大家&#xff0c;如何利用 API 管理工具做 Websocket 测试。 在线 Demo 链接&#xff1a;Postcat - Open Source API Ecosys…

广域网技术(PAP和CHAP)

第十六章&#xff1a;广域网技术 随着经济全球化与数字化变革加速&#xff0c;企业规模不断扩大&#xff0c;越来越多的分支机构出现在不同的地域。每个分支的网络被认为一个LAN&#xff08;Local Area Network&#xff0c;局域网&#xff09;&#xff0c;总部和各分支机构之间…

音频(九)——I2S 输出正弦波

I2S 输出正弦波 PC 端&#xff1a;先生成一个正弦波数组MCU 端&#xff1a;将正弦波数组使用 I2S 输出AP 端&#xff1a;接受从 MCU I2S 端口出来的正弦波数据并测量 THDN 等数据 PC 端生成正弦波数组 原理 三角函数的公式 yAsinxy AsinxyAsinx A 表示幅值 代码实现 源…

深入浅出C++ ——容器适配器

文章目录一、容器适配器二、deque类简介1. deque的原理2. deque迭代器3. deque的优点和缺陷4. 为什么选择deque作为stack和queue的底层默认容器一、容器适配器 适配器的概念 适配器是STL六大核心组件之一&#xff0c;它是一种设计模式&#xff0c;该种模式是将一个类的接口转换…

国家级高新区企业主要经济指标(2012-2021年)

数据来源&#xff1a;国家统计局 时间跨度&#xff1a;2012-2021 区域范围&#xff1a;全国&#xff08;及各分类统计指标&#xff09; 指标说明&#xff1a;手工提取最新的中国统计年鉴数据中各个excel指标表&#xff0c;形成各个指标文件的多年度数据&#xff0c;便于多年…

SpringBoot整合Spring Security过滤器链加载执行流程源码分析

文章目录1.引言2.Spring Security过滤器链加载1.2.注册名为 springSecurityFilterChain的过滤器2、查看 DelegatingFilterProxy类3.查看 FilterChainProxy类3.1 查看 doFilterInternal方法。3.2 查看 getFilters方法。4 查看 SecurityFilterChain接口5 查看 SpringBootWebSecur…

90%的人都理解错了HTTP中GET与POST的区别

Get和Post是HTTP请求的两种基本方法&#xff0c;要说它们的区别&#xff0c;接触过WEB开发的人都能说出一二。 最直观的区别就是Get把参数包含在URL中&#xff0c;Post通过request body传递参数。 你可能自己写过无数个Get和Post请求&#xff0c;或者已经看过很多权威网站总结…

制造企业为何要上数字化工厂系统?

以目前形势来看&#xff0c;数字化转型是制造企业生存的关键&#xff0c;而数字化工厂管理系统是一个综合性、系统性的工程&#xff0c;波及整个企业及其供应链生态系统。数字化工厂系统所要实现的互联互通系统集成、数据信息融合和产品全生命周期集成&#xff0c;将方方面面的…

国产真无线蓝牙耳机哪个好?国产半入耳蓝牙耳机推荐

近几年&#xff0c;生活中随处可见的有戴蓝牙耳机的人&#xff0c;而蓝牙耳机也因为使用更便捷、功能更先进受到了不少用户的喜爱。蓝牙耳机按照佩戴方式来划分&#xff0c;可以有入耳式、半入耳式、头戴式等。在此&#xff0c;我来给大家推荐几款国产半入耳蓝牙耳机&#xff0…

数字IC设计工程师是做什么的?

随着我国半导体产业的发展&#xff0c;近几年的新入行的从业人员&#xff0c;除了微电子相关专业的&#xff0c;还有就是物理、机械、数学、计算机等专业&#xff0c;很多人对这一高薪行业充满了好奇&#xff0c;那么数字IC设计工程师到底是做什么的&#xff1f; 首先来看看数…

每日一题——L1-069 胎压监测(15)

L1-069 胎压监测 分数 15 小轿车中有一个系统随时监测四个车轮的胎压&#xff0c;如果四轮胎压不是很平衡&#xff0c;则可能对行车造成严重的影响。 让我们把四个车轮 —— 左前轮、右前轮、右后轮、左后轮 —— 顺次编号为 1、2、3、4。本题就请你编写一个监测程序&#…