Java中异常的详细讲解与细节讨论

用一个代码引出异常为什么要使用异常

代码:

public static void main(Sting args[]){int n1 = 1;int n2 = 0;System.out.println(n1/n2);//这里会抛ArihmaticException,因为除数不能为0,若未用异常处理机制则程序直接结束,后面的代码将不执行。这样很不好,我们不能因为一个非致命的错误而结束整个程序...
}

异常的基本介绍:

        在Java中,异常是指在程序执行过程中发生的错误或异常情况。Java中的异常处理机制允许我们捕获和处理这些异常,以便程序能够继续执行或进行适当的处理。

异常分为两类:

        (1)编译时异常,是编译器要求解决的异常,必须解决,否则程序跑不起来。如:ClassNotFounfException(找不到类异常)...

        (2)运行时异常,编译器检查不出来,一般是指编程时的逻辑错误,程序员应当避免。如:NullPointerException(空指针异常),ArithmeticException(数学运算异常),ArrayIndexOutOfBoundsException(数组下标越界异常),ClassCastException(类型转换异常),NumberFormatException(数字格式不正确异常)...

NullPointerException(空指针异常)代码:

public class NullPointException {public static void main(String[] args) {//当应用程序试图在需要对象的地方使用null时,抛出该异常String name1 = null;String name2 = "";try {System.out.println(name1.length());//空指针} catch (Exception e) {e.printStackTrace();}System.out.println(name2.length());}
}

ArithmeticException(数学运算异常)代码:

public class ArithmeticException {public static void main(String[] args) {//当出现异常的运算条件时,抛出此异常int n1 = 1;int n2 = 0;try {System.out.println(n1/n2);//除数不能为0} catch (Exception e) {
//            e.printStackTrace();System.out.println(e.getMessage());}}
}

 ArrayIndexOutOfBoundsException(数组下标越界异常)代码:

public class ArrayIndexOutOfBoundsException {public static void main(String[] args) {//用非法索引访问数组时抛出的异常int[] array = {1,2,3};for (int i = 0; i <= array.length; i++) {System.out.println(array[i]);//数组越界了,。没有array[3]}}
}

ClassCastException(类型转换异常)代码:

public class ClassCastException {public static void main(String[] args) {A b = new B();//向上转型B b2 = (B)b;//向下转型//当试图将对象强制转换为不是实例的子类时,抛出该异常C c = (C) b;//这里会抛出ClassCastException,因为B类和C类没有关系,并不能类型转换}
}class A{}
class B extends A{}
class C extends A{}

 NumberFormatException(数字格式不正确异常)代码:

public class NumberFormatException {public static void main(String[] args) {String name2 = "123";int n2 = Integer.parseInt(name2);System.out.println(n2);//当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常//当要把字符串转换为数字时,但是该字符串不能转换为数字时抛出的异常String name1 = "ret";int n1 = Integer.parseInt(name1);//这里会抛出NumberFormatException,因为ret不能转换为数字System.out.println(n1);}
}

异常处理方式:

        (1)try-catch-finally,程序员在代码中捕获发生的异常,自行处理。(就地解决)

        (2)throws,将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者是JVM,而JVM的处理就是直接报错,结束程序

try-catch-finally处理机制示意图:

 throws处理机制示意图:

 try-catch-finally细节讨论:

        (1)如果try块中的异常发生了,则异常发生后面的代码不会执行,直接进入到 catch 块

        (2)如果异常没有发生,则顺序执行 try 的代码块,不会进入到 catch块中

        (3)如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则将代码放在finally块中

代码:

public static void main(String args[]){try {String str = "ret";int a = Integer.parseInt(str);System.out.println("数字:" + a);} catch (Exception e) {System.out.println("异常信息=" + e.getMessage());} finally {System.out.println("finally的代码块被执行");}System.out.println("程序继续...");}
/*
输出结果:异常信息=For input string: "ret"finally的代码块被执行程序继续...
*/

        (4)可以有多个catch语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前

代码:

public class TryCatchFinallyDetails {public static void main(String[] args) {//1.如果 try 代码块有可能有多个异常//2.可以使用多个 catch 分别捕获不同的异常,相应处理//3.要求子类异常写在前面,父类异常写在后面try {People people = new People();System.out.println(people.getName());//NullPointerExceptionint 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) {//Exception是ArithmeticException和NullPointerException的父类System.out.println(e.getMessage());} finally {System.out.println("执行finally语句");}}
}class People {private String name = "ret";public String getName() {return name;}
}/*输出结果:ret算术异常=/ by zero执行finally语句
*/

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

代码:

public static void main(String[] args) {
/*
可以进行 try-finally 配合使用, 这种用法相当于没有捕获异常,
因此程序会直接崩掉/退出。应用场景,就是执行一段代码,不管是否发生异常,
都必须执行某个业务逻辑
*/try {int n1 = 10;int n2 = 0;System.out.println(n1 / n2);} finally {System.out.println("执行了 finally..");}System.out.println("程序继续执行..");
}

throws细节讨论: 

        (1)对于运行时异常,程序中如果没有处理,默认就是throws的方式处理

        (2)子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么抛出的异常类型是父类抛出异常的子类型

        (3)在throws过程中,如果有try_catch,就相当于处理异常了,就不必throws了

代码:

package com.example.retcode.test.exception.throws_;import java.io.FileInputStream;
import java.io.FileNotFoundException;/*** @author ruientao* @version 1.0* 2023/8/21 21:11* @description TODO*/
public class ThrowsDetails {public static void main(String[] args) {f2();}public static void f2() /*没有进行try_catch处理异常,就默认了throws,而且是throws ArithmeticException*/ {//1.对于编译异常,程序中必须处理,比如try-catch或者throws//2.对于运行时异常,程序中如果没有处理,默认就是throws的方式处理int n1 = 10;int n2 = 0;double res = n1 / n2;}public static void f1() throws FileNotFoundException {//调用f3()会报错//1. 因为 f3() 方法抛出的是一个编译异常,即这时,就要 f1() 必须处理这个编译异常,在f1()中,要么try-catch-finally,或者继续throws这个编译异常f3(); // 抛出异常}public static void f3() throws FileNotFoundException {FileInputStream fis = new FileInputStream("d://java.txt");}public static void f4() {//在 f4()中调用方法f5()是可以的,原因是f5()抛出的是运行异常//在java中,并不要求程序员显示处理,因为有默认处理机制f5();}public static void f5() throws ArithmeticException {}
}class Father { //父类public void method() throws RuntimeException {}
}class Son extends Father {//子类//子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常类型的子类型//在throws过程中,如果有方法try-catch,就相当于处理异常,就可以不必throws@Overridepublic void method() throws ArithmeticException {}
}

自定义异常:

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

细节讨论:

        (1)自定义异常类名(程序员自己定),继承Exception或RuntimeException

        (2)如果继承Exception,属于编译异常,如果继承RuntimeException,属于运行异常(一般来说继承RuntimeException,好处时,我们可以使用默认的处理机制,比较方便)

代码:

public class CustomException {public static void main(String[] args) /*throws AgeException*/ {int age = 158;//要求范围在 18 – 120 之间,否则抛出一个自定义异常if (!(age >= 18 && age <= 120)) {//这里我们可以通过构造器,设置信息try {throw new AgeException("年龄需要在 18~120 之间");} catch (AgeException e) {System.out.println(e.getMessage());}} else {System.out.println("你的年龄范围正确:" + age + "岁");}}
}class AgeException extends RuntimeException {public AgeException(String message) {//构造器super(message);}
}

throw 和 throws 的区别

 

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

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

相关文章

windows ipv4 多ip地址设置,默认网关跃点和自动跃点是什么意思?(跃点数)

文章目录 Windows中的IPv4多IP地址设置以及默认网关跃点和自动跃点的含义引言IPv4和IPv6&#xff1a;简介多IP地址设置&#xff1a;Windows环境中的实现默认网关跃点&#xff1a;概念和作用自动跃点&#xff1a;何时使用&#xff1f;关于“跃点数”如何确定应该设置多少跃点数&…

我的创作纪念日(C++修仙练气期总结)

分享自己最喜欢的一首歌&#xff1a;空想フォレスト—伊東歌詞太郎 机缘 现在想想自己在CSDN创作的原因&#xff0c;一开始其实就是想着拿着博客当做自己的学习笔记&#xff0c;笔记嘛&#xff0c;随便写写&#xff0c;自己看得懂就ok了的态度凸(艹皿艹 )。也是用来作为自己学习…

vue3+element下拉多选框组件

<!-- 下拉多选 --> <template><div class"select-checked"><el-select v-model"selected" :class"{ all: optionsAll, hidden: selectedOptions.data.length < 2 }" multipleplaceholder"请选择" :popper-app…

vite 项目搭建

1. 创建 vite 项目 npm create vite@latest 2. 安装sass/less ( 一般我使用sass ) cnpm add -D sasscnpm add -D less 3. 自动导入 两个插件 使用之后,不用导入vue中hook reactive ref cnpm install -D unplugin-vue-components unplugin-auto-import 在 vite.config.…

STM32设置为I2C从机模式(HAL库版本)

STM32设置为I2C从机模式&#xff08;HAL库版本&#xff09; 目录 STM32设置为I2C从机模式&#xff08;HAL库版本&#xff09;前言1 硬件连接2 软件编程2.1 步骤分解2.2 测试用例 3 运行测试3.1 I2C连续写入3.2 I2C连续读取3.3 I2C单次读写测试 4 总结 前言 我之前出过一篇关于…

Claude 2 国内镜像站

Claudeai是什么&#xff1f; Claude 2被称为ChatGPT最强劲的竞争对手&#xff0c;支持100K上下文对话&#xff0c;并且可以同时和5个文档进行对话&#xff0c;不过国内目前无法正常实用的&#xff0c;而claudeai是一个Claude 2 国内镜像站&#xff0c;并且免翻可用&#xff0…

实验三 HBase1.2.6安装及配置

系列文章目录 文章目录 系列文章目录前言一、HBase1.2.6的安装二、HBase1.2.6的配置2.1 单机模式配置2.2 伪分布式模式配置 总结参考 前言 在安装HBase1.2.6之前&#xff0c;需要安装好hadoop2.7.6。 本篇文章参考&#xff1a;HBase2.2.2安装和编程实践指南 一、HBase1.2.6的安…

Android---- 一个完整的小项目(消防app)

前言&#xff1a; 针对不同群体的需求&#xff0c;想着应该拓展写方向。医疗app很受大家喜欢&#xff0c;就打算顺手写个消防app&#xff0c;里面基础框架还是挺简洁 规整的。登陆注册和本地数据库写的便于大家理解。是广大学子的毕设首选啊&#xff01; 此app主要为了传递 消防…

代码随想录打卡—day24—【回溯】— 基础最新8.20+8.22

1 理论基础 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。回溯算法——回溯和递归是相辅相成的。回溯法的效率&#xff0c;回溯法其实就是暴力查找&#xff0c;并不是什么高效的算法。回溯法解决的问题都可以抽象为树形结构&#xff08;N叉树&#xff09; 1.1…

redis 7高级篇1 redis的单线程与多线程

一 redis单线程与多线程 1.1 redis单线程&多线程 1.redis的单线程 redis单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的&#xff0c;Redis在处理客户端的请求时包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理…

【第三阶段】kotlin语言的内置函数let

1.使用普通方法对集合的第一个元素相加 fun main() {//使用普通方法对集合的第一个元素相加var list listOf(1,2,3,4,5)var value1list.first()var resultvalue1value1println(result) }执行结果 2.使用let内置函数对集合的第一个元素相加 package Stage3fun main() {//使用…

Android进阶之路 - 去除EditText内边距

正如题名&#xff0c;在Android中的EditText是自带内边距的&#xff0c;常规而言设置背景为null即可&#xff0c;但是因为使用了并不熟悉的声明式框架&#xff0c;本是几分钟解决的事儿&#xff0c;却花费了小半天~ 简单的需求&#xff0c;相关blog Android进阶之路 - 去除Edi…

探索智能文字识别:技术、应用与发展前景

探索智能文字识别&#xff1a;技术、应用与发展前景 前言一张图全览大赛作品解读随心记你不对我对小结 智能文字识别体系化解读图像预处理文字定位和分割文字区域识别图像校正字体识别和匹配结果后处理小结 如何应对复杂场景下挑战复杂场景应对方法小结 人才时代对人才要求合合…

MyBatis快速入门以及环境搭建和CRUD的实现

目录 前言 一、MyBatis简介 1.MyBatis是什么 2.MyBatis的特点 3.mybatis的作用 4.MyBatis的应用场景 5.MyBatis优缺点 二、相关概念 1.ORM概述 2.常见的ORM框架 3.什么是持久层框架 三、MyBatis的工作原理 1.框架交互 2.工作原理 ​编辑 四、MyBatis环境搭建 1…

Linux Kernel 4.12 或将新增优化分析工具

到 7 月初&#xff0c;Linux Kernel 4.12 预计将为修复所有安全漏洞而奠定基础&#xff0c;另外新增的是一个分析工具&#xff0c;对于开发者优化启动时间时会有所帮助。 新的「个别任务统一模型」&#xff08;Per-Task Consistency Model&#xff09;为主要核心实时修补&#…

软件开发之低代码平台实践

一、低代码、零代码、纯代码定义 低代码开发平台使企业在不编写大量代码的情况下快速创建复杂应用程序。与传统的纯代码开发相比&#xff0c;低代码开发能够大大减少开发周期&#xff0c;并降低技术门槛&#xff0c;使得开发过程更加高效。而零代码开发更进一步简化了开发过程&…

C++信息学奥赛1121:计算矩阵边缘元素之和

题解&#xff1a;i0 or j0 or in-1 or jm-1 or in-1 or jm-1 代码&#xff1a; #include<iostream> // 包含输入输出流库 #include<cmath> // 包含数学函数库 using namespace std; // 使用标准命名空间int main() {int n,m;cin>>n>>m; // 输入…

【Java从0到1学习】10 Java常用类汇总

1. System类 System类对读者来说并不陌生&#xff0c;因为在之前所学知识中&#xff0c;需要打印结果时&#xff0c;使用的都是“System.out.println();”语句&#xff0c;这句代码中就使用了System类。System类定义了一些与系统相关的属性和方法&#xff0c;它所提供的属性和…

基础论文学习(2)——DETR

目标检测 DETR&#xff1a;End-to-End Detection with Transformer detr是facebook提出的引入transformer到目标检测领域的算法&#xff0c;效果很好&#xff0c;做法也很简单&#xff0c;相较于RCNN和YOLO系列算法&#xff0c;避免了Proposal/AnchorNMS的复杂流程。 1. detr…

Faster RCNN网络数据流总结

前言 在学习Faster RCNN时&#xff0c;看了许多别人写的博客。看了以后&#xff0c;对Faster RCNN整理有了一个大概的了解&#xff0c;但是对训练时网络内部的数据流还不是很清楚&#xff0c;所以在结合这个版本的faster rcnn代码情况下&#xff0c;对网络数据流进行总结。以便…