了解异常的特性

导言:

在代码时,即使尽可能的避开错误,但在程序的与运行过程中难免会出现问题,它可能会导致程序中断或出现不可预料的结果。本篇文章主要对异常出现时如何进行处理,以及如何尽量将异常实现可控化,进行概述。

目录

导言:

正文:

一.异常的概念和体系结构

二.异常的分类

三.异常的处理

四.自定义异常 

总结:


正文:

一.异常的概念和体系结构

在Java中,将程序执行过程中发生的不正常行为或者在程序执行过程中出现的问题或意外情况称为异常。在Java中,异常是以对象的形式表示的,它们都是Throwable类的子类。Java的异常体系结构主要包括Throwable、Exception和Error三个关键类。

  1. Throwable类:Throwable是所有异常类的基类,它有两个重要的子类:Exception和Error。Throwable类定义了一些重要的方法,比如getMessage()用于获取异常的描述信息、printStackTrace()用于打印异常堆栈信息等。

  2. Exception类:Exception是程序中可以捕获并处理的异常的基类。它又分为两种:编译时异常(Checked Exception)和运行时异常(Unchecked Exception)。编译时异常是在编译时期就会被检查到的异常,需要在代码中显式地进行处理,比如IOException和SQLException等。而运行时异常是在程序运行时才会被检查到的异常,可以选择捕获处理也可以不处理,比如NullPointerException和ArrayIndexOutOfBoundsException等。

  3. Error类:Error是程序中无法处理的严重问题的表示,通常表示虚拟机无法恢复的错误,比如OutOfMemoryError和StackOverflowError等。与Exception不同,Error类通常不需要程序员进行处理,因为它们表示的是程序无法继续执行的严重问题。

来看几个异常的例子:

1. 算术异常:

System.out.println(10 / 0);
// 执行结果
Exception in thread "main" java.lang.ArithmeticException: / by zero

2. 数组越界异常

int[] arr = {1, 2, 3};
System.out.println(arr[100]);
// 执行结果
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100

3. 空指针异常

int[] arr = null;
System.out.println(arr.length);
// 执行结果
Exception in thread "main" java.lang.NullPointerException

 从上述过程中可以看到,java中不同类型的异常,都有与其对应的类来进行描述。

二.异常的分类

异常可能在编译时发生,也可能在程序运行时发生,根据发生的时机不同,可以将异常分为:运行时异常和编译时异常。

  1. Checked Exception(编译时异常):

    • Checked Exception是在编译时期就会被检查到的异常,必须在代码中显式地进行处理,否则编译器会报错。这种异常通常是程序本身无法处理的外部情况,比如文件不存在、网络连接中断、数据库访问错误等。
    • Checked Exception是Exception类的子类,通常需要使用try-catch块或者throws关键字来处理。在方法的声明中使用throws关键字声明可能抛出的Checked Exception,以便通知调用者处理这些异常。
    • 一些常见的Checked Exception包括IOException、SQLException、ClassNotFoundException等。

具体代码实例:

public class Person {
private String name;
private String gender;
int age;
// 想要让该类支持深拷贝,覆写Object类的clone方法即可
@Override
public Person clone() {
return (Person)super.clone();
}
}
编译时报错:
Error:(17, 35) java: 未报告的异常错误java.lang.CloneNotSupportedException; 必须对其进行捕获或声明以便抛出
  1. Unchecked Exception(运行时异常):

    • Unchecked Exception是在程序运行时才会被检查到的异常,不要求程序员显式地进行处理,可以选择捕获处理也可以不处理。这种异常通常是由程序逻辑错误或者运行环境导致的,比如空指针引用、数组越界、类型转换错误等。
    • Unchecked Exception是RuntimeException类的子类,它们通常是由程序员编码不当或者程序运行环境出现问题所导致的。在实际编程中,程序员应该尽量避免出现这类异常,以提高程序的健壮性和可靠性。
    • 一些常见的Unchecked Exception包括NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException等。

具体代码实例:

public class RuntimeExceptionExample {public static void main(String[] args) {try {int[] arr = new int[5];int value = arr[10]; // 这里会抛出ArrayIndexOutOfBoundsException} catch (ArrayIndexOutOfBoundsException e) {System.out.println("捕获到数组越界异常:" + e.getMessage());}// 模拟空指针异常String str = null;try {System.out.println(str.length()); // 这里会抛出NullPointerException} catch (NullPointerException e) {System.out.println("捕获到空指针异常:" + e.getMessage());}// 模拟类型转换异常try {Object obj = "Hello";Integer num = (Integer) obj; // 这里会抛出ClassCastException} catch (ClassCastException e) {System.out.println("捕获到类型转换异常:" + e.getMessage());}}
}

在上面的示例中,我们故意制造了几种运行时异常的情况,分别是数组越界、空指针引用和类型转换异常。然后使用try-catch块来捕获这些异常,并输出异常信息。这样可以避免程序因为这些异常而终止,同时也可以根据具体的异常信息来进行相应的处理。

三.异常的处理

异常处理是指在程序运行过程中,当程序发生异常时,如何进行相应的处理。异常处理的目的是保证程序的稳定性和可靠性,避免程序因为异常而崩溃或者出现不可预料的错误。Java提供了一套完整的异常处理机制,程序员可以使用这些机制来捕获和处理异常。

Java中的异常处理机制主要包括以下几个方面:

1.抛出异常:

当程序出现异常时,可以使用throw关键字手动抛出一个异常对象,这个异常对象可以是Java内置的异常类,也可以是自定义的异常类。

在编写程序时,如果程序中出现错误,此时就需要将错误的信息告知给调用者,比如:参数检测。
在Java中,可以借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者。具体语法如下:

throw new XXXException("异常产生的原因");

具体代码实例:

public static int getElement(int[] array, int index){
//实现一个获取数组中任意位置元素的方法。
if(null == array){
throw new NullPointerException("传递的数组为null");
}
if(index < 0 || index >= array.length){
throw new ArrayIndexOutOfBoundsException("传递的数组下标越界");
}
return array[index];
}
public static void main(String[] args) {
int[] array = {1,2,3};
getElement(array, 3);
}

 上述代码会对传进来的数组进行判断,如果出现了空数组或者越界的情况会抛出指定的异常信息提醒程序员。

注意事项:

  • throw必须写在方法体内部
  • 抛出的对象必须是Exception 或者 Exception 的子类对象
  • 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理
  • 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
  • 异常一旦抛出,其后的代码就不会执行

2.捕获异常:

异常的捕获,也就是异常的具体处理方式,主要有两种:异常声明throws 以及 try-catch捕获处理。在程序中使用try-catch块来捕获异常,如果try块中的代码出现了异常,就会跳转到catch块中进行异常处理。catch块中可以根据异常类型来进行相应的处理,比如输出异常信息、重新抛出异常、返回默认值等。

处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想处理该异常,此时就可以借助throws将异常抛给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常。

语法格式:
修饰符 返回值类型 方法名(参数列表) throws 异常类型1,异常类型2...{
}

 throws对异常并没有真正处理,而是将异常报告给抛出异常方法的调用者,由调用者处理。如果真正要对异常进行处理,就需要try-catch。

语法格式:
try{
// 将可能出现异常的代码放在这里
}catch(要捕获的异常类型 e){
// 如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常类型一致时,或者是try中抛出异常的基类
时,就会被捕获到
// 对异常就可以正常处理,处理完成后,跳出try-catch结构,继续执行后序代码
}[catch(异常类型 e){
// 对异常进行处理
}finally{
// 此处代码一定会被执行到
}]
// 后序代码
// 当异常被捕获到时,异常就被处理了,这里的后序代码一定会执行
// 如果捕获了,由于捕获时类型不对,那就没有捕获到,这里的代码就不会被执行
注意:
1. []中表示可选项,可以添加,也可以不用添加
2. try中的代码可能会抛出异常,也可能不会

 finally块:finally块中的代码无论是否发生异常,都会被执行。通常在finally块中进行一些资源释放的操作,比如关闭文件、关闭数据库连接等。

具体代码实例:

public class ExceptionHandlingExample {public static void main(String[] args) {try {int a = 10 / 0; // 这里会抛出ArithmeticException} catch (ArithmeticException e) {System.out.println("捕获到算术异常:" + e.getMessage());} finally {System.out.println("finally块中的代码被执行");}}
}

在上面的示例中,我们故意制造了一个除以0的异常,然后使用try-catch块来捕获这个异常,并输出异常信息。同时,在finally块中输出一条信息,无论是否发生异常,这条信息都会被输出。这样可以保证程序的稳定性和可靠性。

流程总结:

  1. 程序先执行 try 中的代码
  2. 如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.
  3. 如果找到匹配的异常类型, 就会执行 catch 中的代码
  4. 如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.
  5. 无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).
  6. 如果上层调用者也没有处理的了异常, 就继续向上传递.
  7. 一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止.

注意事项:

  • try块内抛出异常位置之后的代码将不会被执行
  • 如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到JVM收到后中断程序----异常是按照类型来捕获的 
  •  try中可能会抛出多个不同的异常对象,则必须用多个catch来捕获----即多种异常,多次捕获,如果异常之间具有父子关系,一定是子类异常在前catch,父类异常在后catch,否则语法错误:

四.自定义异常 

在Java中,除了使用Java内置的异常类来处理异常外,还可以自定义异常类来处理特定的异常情况。自定义异常类可以继承自Exception或者RuntimeException类,也可以实现Throwable接口,以实现我们自己的异常处理逻辑。

自定义异常通常包括以下几个方面:

  1. 继承Exception或者RuntimeException类:自定义异常类通常继承自Exception或者RuntimeException类,这样可以让我们的自定义异常类具有和Java内置异常类相同的特性和行为。

  2. 添加构造方法:自定义异常类通常需要添加构造方法,用于初始化异常信息。通常情况下,我们会添加一个带有字符串参数的构造方法,用于传递异常信息。

  3. 添加异常信息:自定义异常类通常需要添加异常信息,用于描述异常的原因和情况。我们可以通过重写getMessage()方法来实现这个功能。

具体代码实例:

public class MyException extends Exception {
//自定义的异常类,用于对异常进行自定义的处理public MyException(String message) {super(message);}@Overridepublic String getMessage() {return "自定义异常:" + super.getMessage();}
}
public class CustomExceptionExample {
//当出现指定异常时,引用指定的异常对象public static void main(String[] args) {try {throw new MyException("这是一个自定义异常");} catch (MyException e) {System.out.println(e.getMessage());}}
}

 在这段代码中,我们通过throw关键字手动抛出了一个MyException类型的异常,并在catch块中捕获了这个异常。最终,我们输出了异常信息,这里的异常信息包括了我们自定义的文本和传递进来的异常信息。

注意事项:

  • 自定义异常通常会继承自 Exception 或者 RuntimeException
  • 继承自 Exception 的异常默认是受查异常
  • 继承自 RuntimeException 的异常默认是非受查异常

总结:

在实际编程中,合理地处理异常可以提高程序的健壮性和可靠性。正确地处理异常不仅可以避免程序崩溃,还可以提供更好的用户体验。正确的使用异常还能即使告诉程序员出错的原因,不必花大量的时间进行调试,加快开发的效率。

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

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

相关文章

stm32 HSUSB

/ stm32f407xx.h #define USB_OTG_HS_PERIPH_BASE 0x40040000UL #define USB_OTG_HS ((USB_OTG_GlobalTypeDef *) USB_OTG_HS_PERIPH_BASE) // // 定义全局变量 USBD_HandleTypeDef hUsbDeviceHS;并默认全零初始化/* USB Device handle structure */ typedef struct _USB…

4月2日-3日·上海 | 3DCC 第二届3D细胞培养与类器官研发峰会携手CGT Asia 重磅来袭

类器官&#xff08;Organoids&#xff09;作为干细胞研究领域最重要的成果之一&#xff0c;在基础医学研究、转化医学及药物研发领域展现出巨大的应用潜力&#xff0c;特别是在精准医疗以及药物安全性和有效性评价等方向凭借其先天优势引起了极大的市场关注&#xff0c;成为各大…

无线WiFi安全渗透与攻防(一) 无线安全环境搭建以及密码生成

无线WiFi安全渗透与攻防 一. 无线安全环境搭建1.802.11标准(1).概念(2). 802.11标准和补充2.WiFi标准3.无线接入点AP(Access Point)1.概念2.AP的分类(1).胖AP(2).瘦AP(3).用途的区别4.客户端 STA5.无线局域网AP术语介绍6.无线网卡的工作模式(1).Managed Mode(2).…

【智能家居】5、主流程设计以及外设框架编写与测试

目录 一、主流程设计 1、工厂模式结构体定义 &#xff08;1&#xff09;指令工厂 inputCmd.h &#xff08;2&#xff09;外设工厂 controlDevices.h 二、外设框架编写 1、创建外设工厂对象bathroomLight 2、编写相关函数框架 3、将浴室灯相关操作插入外设工厂链表等待被调…

pm2在Windows环境中的使用

pm2 进程管理工具可以Windows操作系统上运行&#xff0c;当一台Windows电脑上需要运行多个进程时&#xff0c;或者运维时需要运行多个进程以提供服务时。可以使用pm2&#xff0c;而不再是使用脚本。 1. 使用PM2管理进程 1.1. 启动PM2项目 1.1.1. 直接启动项目 参数说明&…

springboot集成nacos并实现自动刷新

目录 1.说明 2.示例 3.自动刷新的注意点 1.说明 springboot项目中存在好多配置文件&#xff0c;比如配置数据信息&#xff0c;redis信息等等&#xff0c;配置文件可以直接放在代码&#xff0c;也可以放在像nacos这样的组件中&#xff0c;实现动态的管理&#xff0c;修改配置…

浅谈滑动窗口

滑动窗口是什么&#xff1f; 滑动窗口其实是一个想象出来的数据结构。有左边界L和有边界R。 举例来说&#xff1a;数组 arr {3,1,5,7,6,5,8}; 其窗口就是我们规定的一个运动轨迹。 最开始时&#xff0c;边界LR都在数组的最左侧&#xff0c;此时没有包住任何数。 此时规定&…

ExoPlayer架构详解与源码分析(9)——TsExtractor

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player ExoPlayer架构详解与源码分析&#xff08;3&#xff09;——Timeline ExoPlayer架构详解与源码分析&#xff08;4&#xff09;—…

linux进程之进程的优先级➕环境变量

文章目录 1.优先级的认识1.1优先级的介绍1.2初识优先级1.3ps指令1.4查看/修改进程的优先级1.5对优先级的认识1.6对进程的深一步理解 2.环境变量2.0环境变量相关的命令2.1环境变量的概念2.2常见/查看环境变量2.3环境变量的作用2.4修改环境变量1.将zombie可执行程序放到PATH现有的…

Apache Doris安装部署

Apache Doris安装部署 版本&#xff1a; CentOS 7.6 Apache Doris 0.14.0 编译 选择合适的版本进行下载&#xff0c;此次选择0.14.0版本 下载 | Apache Doris 一、CentOS编译 1 安装依赖 sudo yum groupinstall Development Tools && sudo yum install maven c…

CF1899B 250 Thousand Tons of TNT

题目链接 题目 题目大意 T T T 组测试数据 每组 n n n 个货物&#xff0c;第 i i i 个货物 的重量是 a i a_i ai​ 用k辆货车按顺序装这些货物&#xff0c;条件是每辆车上的货物个数都一样&#xff0c;也即是说 n n n 必须能被 k k k 整除&#xff0c; 求任意两辆车货物总…

开发中常用的日期转换

一、java中日期转换 场景再现&#xff1a;前端给我们传的日期格式通常为 2023-11-16&#xff0c;而数据库在某些场景下会将时间存为20231106&#xff08;yyyyMMdd&#xff09;的格式 1.方法一 使用字符串分隔 String date"2023-11-16"; String newDate date.replace…

对象和数据结构

文章目录 前言一、从链式调用说起二、数据抽象三、数据、对象的反对称性四、得墨忒尔律五、数据传送对象总结 前言 代码整洁之道读书随笔&#xff0c;第六章 一、从链式调用说起 面向对象语言中常用的一种调用形式&#xff0c;链式调用&#xff0c;是一种较受推崇的编码风格&…

Alibaba Nacos注册中心实战

为什么需要注册中心 思考&#xff1a;网络请求&#xff0c;如果服务提供者发生变动&#xff0c;服务调用者如何感知服务提供者的ip和端口变化&#xff1f; // 微服务之间通过RestTemplate调用&#xff0c;ip:port写死&#xff0c;如果ip或者port变化呢&#xff1f; String ur…

【c++】左值和右值

理解 C/C 中的左值和右值 写得很好 简单定义 左值(lvalue, locator value) 表示一个占据内存中某个可识别得位置&#xff08;地址&#xff09;得对象右值(rvalue), 不是左值就是右值&#xff0c; 不表示内存中某个可识别位置的对象的表达式。 举例&#xff1a; int var; va…

【学习笔记】Java安全之动态加载字节码

文章目录 什么是Java的字节码利用URLClassLoader加载远程class文件利用ClassLoader#defineClass直接加载字节码利用TemplatesImpl加载字节码利用BCEL ClassLoader加载字节码 最近在学习Phith0n师傅的知识星球的Java安全漫谈系列&#xff0c;随手记下笔记 什么是Java的字节码 J…

CCRC认证是什么?

什么是CCRC认证&#xff1f; 信息安全服务资质&#xff0c;是信息安全服务机构提供安全服务的一种资格&#xff0c;包括法律地位、资源状况、管理水平、技术能力等方面的要求。 信息安全服务资质&#xff08;CCRC&#xff09;是依据国家法律法规、国家标准、行业标准和技术规范…

iOS学习 --- Xcode 15 下载iOS_17.0.1_Simulator失败解决方法

1.去开发者官网下载安装包 https://developer.apple.com/download/all/?qiOS%2017 使用浏览器下载。 2.打开终端通过命令添加到xcode 命令如下&#xff1a; sudo xcode-select -s /Applications/Xcode.app(输入开始密码)xcodebuild -runFirstLaunch (等待一小会)xcrun simctl…

翻译软件Mate Translate mac中文版介绍说明

Mate Translate mac可以帮你翻译超过100种语言的单词和短语&#xff0c;使用文本到语音转换&#xff0c;并浏览历史上已经完成的翻译。你还可以使用Control S在弹出窗口中快速交换语言。 Mate Translate Mac版软件介绍 Mate Translate 可以在你的所有设备之间轻松同步&#x…

人参果

《人参果》 作者&#xff0f;罗光记 千年灵气结人参&#xff0c; 果似珍珠色艳新。 仙界奇珍谁得享&#xff0c; 只留传说在人心。