Java异常处理机制

Java异常处理机制

  • 一、异常概述与异常体系结构
    • 异常概述
    • Error示例代码:
    • Exception示例代码:
    • 异常体系结构
    • Error和Exception的区别:
    • 异常分类
    • 检查异常
    • 非检查异常
      • Why:为什么有非检查异常?
      • Where:非检查异常有哪些?
      • Exception异常划分
        • 运行时异常:
        • 编译期异常:
  • 二、初识异常与常见异常
    • 初识异常

一、异常概述与异常体系结构

异常概述

在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的,比如:客户输入数据的格式,读取文件是否存在,网络是否始终保持通畅等等。
程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常(开发过程中的语法错误和逻辑错误不是异常)。
Java程序在执行过程中所发生的异常事件可分为两类:
Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError(栈溢出)和OOM(内存溢出)。一般不编写针对性的代码进行处理。
Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:
空指针访问
试图读取不存在的文件
网络连接中断
数组角标越界

Error示例代码:

public class ErrorTest {public static void main(String[] args) {/** 1、栈溢出:java.lang.StackOverflowError*   原因 : 函数调用栈太深了,注意代码中是否有了循环调用方法而无法退出的情况*   StackOverflowError 是一个java中常出现的错误:在jvm运行时的数据区域中有一个java虚拟机栈,当执行java方法时会进行压栈弹栈的操作。在栈中会保存局部变量,操作数栈,方法出口等等。jvm规定了栈的最大深度,当执行时栈的深度大于了规定的深度,就会抛出StackOverflowError错误。* */main(args);/** 2、堆溢出:java.lang.OutOfMemoryError*   原因:Java中所有的对象都存储在堆中,通常如果JVM无法再分配新的内存,内存耗尽,垃圾回收无法及时回收内存,就会抛出OutOfMemoryError。* */Integer[] arr = new Integer[1024 * 1024 * 1024];}
}

Exception示例代码:

import java.io.FileInputStream;public class ExceptionTest {public static void main(String[] args) {/** 1、运行时异常:java.lang.ArithmeticException*  原因:ArithmeticException* */int a = 10;int b = 0;System.out.println(a / b);/** 2、编译期异常:java.io.FileNotFoundException*   原因:文件找不到异常通常是两种情况:1、系统找不到指定的路径 2、拒绝访问(指定的是目录时,就会报拒绝访问异常)* */FileInputStream fis = new FileInputStream("a.txt");}
}

异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?

Java提供了更加优秀的解决办法:异常处理机制。异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。

Java中的异常可以是函数中的语句执行时引发的,也可以是程序员通过throw 语句手动抛出的,只要在Java程序中产生了异常,就会用一个对应类型的异常对象来封装异常,JRE就会试图寻找异常处理程序来处理异常。

Throwable类是Java异常类型的顶层父类,一个对象只有是 Throwable 类的(直接或者间接)实例,他才是一个异常对象,才能被异常处理机制识别。JDK中内建了一些常用的异常类,我们也可以自定义异常。

异常体系结构

Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类。
Throwable又派生出Error类和Exception类。

错误:Error类以及它的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。

异常:Exception以及它的子类,代表程序运行时发生的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。

Error和Exception的区别:

Error和Exception都有一个共同的根类是Throwable类。

Error是系统中的错误,程序员是不能改变的和处理的,一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。因此我们编写程序时不需要关心这类错误。
Exception,也就是我们经常见到的一些异常情况,表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

异常分类

总体上我们根据Javac对异常的处理要求,将异常类分为2类。

我们常说的异常是狭义上的:就是指Exception及其子类,但是广义上的异常是包括Exception和Error;

Java的异常(包括Exception和Error)从广义上分为检查异常(checked exceptions)和非检查的异常(unchecked exceptions)。

其中根据Exception异常进行划分,可分为运行时异常和非运行时异常。
需要明确的是:检查和非检查是对于javac来说的,这样就很好理解和区分了。

在这里插入图片描述

检查异常

What:什么是检查异常(checked exception)?

就是编译器要求你必须处置的异常。不知道你编程的时候有没有遇到过,你写的某段代码,编译器要求你必须要对这段代码try…catch,或者throws exception,如果你遇见过,没错,这就是检查异常,也就是说,你代码还没运行呢,编译器就会检查你的代码,会不会出现异常,要求你对可能出现的异常必须做出相应的处理。

javac强制要求程序员为这样的异常做预备处理工作(使用try…catch…finally或者throws)。在方法中要么用try-catch语句捕获它并处理,要么用throws子句声明抛出它,否则编译不会通过。这样的异常一般是由程序的运行环境导致的。因为程序可能被运行在各种未知的环境下,而程序员无法干预用户如何使用他编写的程序,于是程序员就应该为这样的异常时刻准备着。如SQLException , IOException,ClassNotFoundException 等。

比如:我们调用日期格式化类解析字符串的时候;

How:怎样处理检查异常(checked exception)?

1、继续抛出,消极的方法,一直可以抛到java虚拟机来处理,就是通过throws Exception抛出。

2、用try…catch捕获

注意,对于检查的异常必须处理,或者必须捕获或者必须抛出

Where:检查异常有哪些呢?

除了RuntimeException与其子类,以及错误(Error),其他的都是检查异常(绝对的大家族)。

非检查异常

What:什么是非检查异常(unchecked exceptions)?

编译器不要求强制处置的异常,虽然你有可能出现错误,但是编译器不会在编译的时候检查,没必要,也不可能。

javac在编译时,不会提示和发现这样的异常,不要求在程序处理这些异常。所以如果愿意,我们可以编写代码处理(使用try…catch…finally)这样的异常,也可以不处理。

对于这些异常,我们应该修正代码,而不是去通过异常处理器处理。这样的异常发生的原因多半是代码写的有问题。如除0错误ArithmeticException,错误的强制类型转换错误ClassCastException,数组索引越界ArrayIndexOutOfBoundsException,使用了空对象NullPointerException等等。

How:对非检查的异常(unchecked exception )怎样处理?

    1、用try...catch捕获2、继续抛出3、不处理4、通过代码处理一般我们是通过代码处理的,因为你很难判断会出什么问题,而且有些异常你也无法运行时处理,比如空指针,需要人手动的去查找。而且,捕捉异常并处理的代价远远大于直接抛出。

Why:为什么有非检查异常?

    你想想非检查异常都有哪些?NullPointerException,IndexOutOfBoundsException,VirtualMachineError等,这些异常你编译的时候检查吗?再说了,明明可以运行时检查,都在编译的时候检查,你写的代码还能看吗?而且有些异常只能在运行时才能检查出来,比如空指针,堆溢出等。

Where:非检查异常有哪些?

    RuntimeException与其子类,以及错误(Error)。

Exception异常划分

    Exception异常进行划分,它可分为运行时异常和编译期异常。
运行时异常:

是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是非检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。

编译期异常:

是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不要自定义检查异常。

二、初识异常与常见异常

初识异常

下面的代码会演示2个异常类型:ArithmeticException 和 InputMismatchException。
前者由于整数除0引发,后者是输入的数据不能被转换为int类型引发。

import java.util.Scanner;public class AllDemo {public static void main(String[] args) {System.out.println("----欢迎使用命令行除法计算器----");CMDCalculate();}public static void CMDCalculate() {Scanner scan = new Scanner(System.in);int num1 = scan.nextInt();int num2 = scan.nextInt();int result = devide(num1, num2);System.out.println("result:" + result);scan.close();}public static int devide(int num1, int num2) {return num1 / num2;}
}/*****************************************
----欢迎使用命令行除法计算器----
2
0
Exception in thread "main" java.lang.ArithmeticException: / by zeroat AllDemo.devide(AllDemo.java:19)at AllDemo.CMDCalculate(AllDemo.java:13)at AllDemo.main(AllDemo.java:6)
----欢迎使用命令行除法计算器----
----欢迎使用命令行除法计算器----
1
r
Exception in thread "main" java.util.InputMismatchExceptionat java.util.Scanner.throwFor(Scanner.java:864)at java.util.Scanner.next(Scanner.java:1485)at java.util.Scanner.nextInt(Scanner.java:2117)at java.util.Scanner.nextInt(Scanner.java:2076)at AllDemo.CMDCalculate(AllDemo.java:12)at AllDemo.main(AllDemo.java:6)
*****************************************/

异常是在执行某个函数时引发的,而函数又是层级调用,形成调用栈的,因为,只要一个函数发生了异常,那么他的所有的caller都会被异常影响。当这些被影响的函数以异常信息输出时,就形成的了异常追踪栈。

异常最先发生的地方,叫做异常抛出点。
从上面的例子可以看出,当devide函数发生除0异常时,devide函数将抛出ArithmeticException异常,因此调用它的CMDCalculate函数也无法正常完成,因此也发送异常,而CMDCalculate的caller——main 因为CMDCalculate抛出异常,也发生了异常,这样一直向调用栈的栈底回溯。这种行为叫做异常的冒泡,异常的冒泡是为了在当前发生异常的函数或者这个函数的caller中找到最近的异常处理程序。由于这个例子中没有使用任何异常处理机制,因此异常最终由main函数抛给JRE,导致程序终止。

上面的代码不使用异常处理机制,也可以顺利编译,因为2个异常都是非检查异常。但是下面的例子就必须使用异常处理机制,因为异常是检查异常。

代码中我选择使用throws声明异常,让函数的调用者去处理可能发生的异常。但是为什么只throws了IOException呢?因为FileNotFoundException是IOException的子类,在处理范围内。

import java.io.FileInputStream;
import java.io.IOException;public class ExceptionTest {public void testException() throws IOException {//FileInputStream的构造函数会抛出FileNotFoundExceptionFileInputStream fileIn = new FileInputStream("E:\\a.txt");int word;//read方法会抛出IOExceptionwhile ((word = fileIn.read()) != -1) {System.out.print((char) word);}//close方法会抛出IOExceptionfileIn.close();}
}

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

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

相关文章

ModuleNotFoundError: No module named ‘pycocotools‘

cuda 12.1 pytorch 2.0.1 python 3.11 运行代码,报该错误,尝试了以下方法解决: 方法一 # step 1: 安装cython pip install Cython# step 2: 安装pycocotools pip install githttps://github.com/philferriere/cocoapi.git#eggpycocotools…

和田2023年群众舞蹈大赛总决赛圆满落幕!

11月19日,由中共和田地委宣传部主办,地区文旅局承办,地区文化馆、各县市文旅局协办,北京市援疆和田指挥部支持的和田地区2023年“大地欢歌 舞动和田”群众舞蹈大赛总决赛在和田市新夜市圆满落幕,比赛最终决出一等奖1名…

Adobe XD免费使用全攻略,详细教程来袭!

Adobexd是一种基于矢量的UI和UX设计工具。设计师可以使用Adobexd进行智能手表揭示设计、网页设计等。由于其强大的设计功能,Adobexd逐渐成为设计界的热门工具。作为一种海外设计工具,Adobexd是否免费也成为很多设计关注的话题,本文将为您解答…

Github Copilot AI编码完成工具

目录 一、GitHub Copilot 1、简介 2、工作原理 3、功能 二、GitHub Copilot X 1、什么是 GitHub Copilot X 2、GitHub Copilot X 的功能 三、支持、使用 1、支持 2、使用 四、实际研究、验证(代码方向) 1、代码生成 2、代码提示 3、生成测试用例 4、代码解释 5…

编译源码-【opencv3.4.16 + vs2013 x64】

编译机器:i5 13500HX RTX 4050 laptop win11 CMake 3.26.4 Configure,去掉勾选图中黄色标注的项,opencv_world 随意 Configure可能提示3rdparty下载timeout,它会下载到源码目录的.cache ├── .cache │ ├──ffmpeg │ │ …

Linux C 网络编程概述

网络编程 计算机网络概述分类网络体系结构通信协议通信流程网络通信帧格式以太网帧格式分析ARP 协议分析IP 数据报分析IP分类IP 分配子网掩码 TCP 段分析 TCP三次握手协议 ⭐TCP四次挥手协议 ⭐ TCP编程基于 TCP 客户端编程-步骤说明基于 TCP 服务器端编程-步骤说明基于 TCP 服…

汽车智能座舱/智能驾驶SOC -1

看到华为&小康的 AITO问界M6、M7各种广告营销、宣传、测评、好评如潮水般席卷网络各APP平台。翻看了中信和海通对特斯拉M3和比亚迪元的拆解报告,也好奇华为的汽车芯片平台又能做出哪些新花样,下面是Mark开头,也学习下智能座舱和智能驾驶芯…

MISRA 2012学习笔记(5)-Rules 8.10

文章目录 Rules8.10 基本类型模型(The essential type model)8.10.1 原理8.10.2 基本类型(Essential type)Rule 10.1 操作数不得具有不适当的基本类型Rule 10.2 在加减法运算中,不得不当使用本质为字符类型的表达式Rule 10.3 表达式的值不得赋值给具有较窄基本类型或…

单线程的JS中Vue导致的“线程安全”问题

目录 现象分析原因 浏览器中Js是单线程的,当然不可能出现线程安全问题。只是遇到的问题的现象与多线程的情况十分相似,导致对不了解Vue实现的我怀疑起了人生… 现象 项目中用到了element-plus中的加载组件,简单封装了一下,用来保…

linux 开发板以太网通过Ubuntu上外网方法

在开发板嵌入式设备,有一个mgbe网卡,用网线与连接soc的网卡,和外接网卡,将网卡usb接口插入电脑,选择接入到Ubuntu系统 在Ubuntu将能识别到这个外接网卡,这样就可以通过Ubuntu和soc通讯了, 如下…

服务案例|故障频发的一周,居然睡得更香!

医院运维有多忙? 医院运维,听起来平平无奇毫不惊艳,但其中的含金量,可不是“维持系统正常运行”就能总结的。毕竟医院对业务连续性的超高要求,让运维面对的问题都是暂时的,下一秒可能就有新问题需要发现解…

双12电视盒子推荐:测评员解析目前电视盒子哪个最好

电视盒子不需要每月缴费,只需联网就可以收看海量视频资源,游戏、网课、投屏等功能让电视盒子的使用场景更丰富,我每年都会进行数十次电视盒子测评,本期要分享的是双十二电视盒子推荐,全面解析目前电视盒子哪个最好。 一…

思福迪 运维安全管理系统 test_qrcode_b 远程命令执行漏洞

思福迪 运维安全管理系统 test_qrcode_b 远程命令执行漏洞 一、漏洞描述二、漏洞影响三、网络测绘四、漏洞复现1.手动复现2.自动化复现3.python源代码 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任…

数据结构——栈的详细介绍

数据结构——栈 一、栈的结构和概念二、 栈的两种构建方式①、用数组进行构建②、用链表进行构建 三、栈的创建四、栈的初始化五、栈的销毁六、压栈七、出栈八、判空九、获取栈顶元素十、获取栈的size 一、栈的结构和概念 栈:栈是一种特殊的线性表,其只…

第15届蓝桥STEMA测评真题剖析-2023年10月29日Scratch编程初中级组

[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第160讲。 第15届蓝桥第2次STEMA测评,这是2023年10月29日举办的STEMA,比赛仍然采取线上形式。这…

Autoware.universe部署06:使用DBC文件进行UDP的CAN通信代码编写

目录标题 一、安装DBC文件编辑工具VectorCANdb二、编写DBC文件2.1 CAN通信协议2.2 编写DBC文件2.2.1 根据CAN协议设置signals2.2.2 设置报文2.2.3 建立节点 三、根据DBC文件编写ROS2驱动程序四、实际通信调试 根据CAN协议编写DBC文件,通过DBC文件编写ROS2包进行UDP通…

jetpack compose中实现丝滑的轮播图效果

写在前面 最近在翻Jetpack库,发现了DataStore,官方是这么说的: Jetpack DataStore 是一种数据存储解决方案,允许您使用协议缓冲区存储键值对或类型化对象。DataStore 使用 Kotlin 协程和 Flow 以异步、一致的事务方式存储数据。 …

laravel引入element-ui后,blade模板中使用elementui时,事件未生效问题(下载element-ui到本地直接引入项目)

背景 重构公司后台项目,使用了dcat-admin,但是dcat-admin有些前端功能不能满足需求。因此引入element-ui进行相关界面的优化 具体流程 1.下载element-ui到本地 2.进入如下目录 打开 node_modules\element-ui\lib 复制index.js 打开 node_modules/ele…

[Linux] shell条件语句和if语句

一、条件语句 1.1 测试 test 测试文件的表达式是否成立 格式:test 条件表达式 [ 条件表达式 ] 选项作用-d测试是否为目录-e测试目录或文件是否存在-a测试目录或文件是否存在-f测试是否为文件-r测试当前用户是否有权限读取-w测试当前用户是否有权限写入-x测试当前…

一键合并多个TXT文本,将保存在TXT的快递单号进行一键合并

如果你需要处理大量的TXT文本文件,那么你可能会遇到需要将这些文件合并为一个文件的情况。这不仅涉及到文件的组织和管理,还可能涉及到文件内容的连贯性和完整性。现在,我们有一个强大的工具,可以帮助你轻松实现一键文件整理&…