Java异常(超详细!)

article/2025/10/30 20:39:26

1、什么是异常,java提供异常处理机制有什么用?

  • 什么是异常:程序执行过程中的不正常情况。
  • 异常的作用:增强程序的 健壮性

eg.

public class ExceptionTest01 {public static void main(String[] args) {int a = 10;int b = 0;// 实际上JVM在执行到此处的时候,会new异常对象:new ArithmeticException("/ by zero");// 并且JVM将new的异常对象抛出,打印输出信息到控制台了。int c = a / b;System.out.println(a + "/" + b + "=" + c);// 此处运行也会创建一个:ArithmeticException类型的异常对象。System.out.println(100 / 0);}
}

2、java语言中异常是以什么形式存在的呢?

异常在java中以 的形式存在,每一个 异常类 都可以创建 异常对象

eg.

public class ExceptionTest02 {public static void main(String[] args) {// 通过“异常类”实例化“异常对象”NumberFormatException nfe = new NumberFormatException("数字格式化异常!");// java.lang.NumberFormatException: 数字格式化异常!System.out.println(nfe);}
}

3、异常继承结构图

在这里插入图片描述

  • Exception的直接子类:编译时异常(要求程序员在编写程序阶段必须预先对这些异常进行处理,如果不处理编译器报错,因此得名编译时异常。)。
  • RuntimeException:运行时异常。(在编写程序阶段程序员可以预先处理,也可以不管,都行。)

4、异常的分类

异常分为 编译时异常运行时异常

所有异常都是在 运行阶段 发生的。因为只有程序运行阶段才可以 new对象。

因为异常的发生就是 new异常对象

4.1编译时异常因为什么而得名?

因为编译时异常必须在编译(编写)阶段预先处理,如果不处理编译器报错,因此得名。

4.2 编译时异常和运行时异常的区别?

  • 编译时异常一般发生的概率 比较高
  • 运行时异常一般发生的概率 比较低
  • 编译时异常发生概率较高,需要在运行之前对其进行 预处理
  • 运行时异常发生概率较低,没必要提前进行预处理。

4.3编译时异常和运行时异常别称

  • 编译时异常
  1. 受检异常:CheckedException
  2. 受控异常
  • 运行时异常
  1. 未受检异常:UnCheckedException
  2. 非受控异常

1、补充:

public class ExceptionTest03 {public static void main(String[] args) {System.out.println(100 / 0);// 这里的HelloWorld没有输出,没有执行。System.out.println("Hello World!");}
}

程序执行到System.out.println(100 / 0);
此处发生了 ArithmeticException 异常,底层 new 了一个ArithmeticException异常对象,然后抛出了。
由于是 main方法 调用了100 / 0,所以这个异常ArithmeticException抛给了main方法
main方法没有处理,将这个异常自动抛给了 JVMJVM最终终止程序的执行

此时System.out.println("Hello World!");并不会执行。

注意:
ArithmeticException 继承 RuntimeException,属于 运行时异常。在编写程序阶段不需要对这种异常进行预先的处理。


eg.

public class ExceptionTest04 {public static void main(String[] args) {// main方法中调用doSome()方法// 因为doSome()方法声明位置上有:throws ClassNotFoundException// 我们在调用doSome()方法的时候必须对这种异常进行预先的处理。// 如果不处理,编译器就报错。//编译器报错信息: Unhandled exception: java.lang.ClassNotFoundExceptiondoSome();}/*** doSome方法在方法声明的位置上使用了:throws ClassNotFoundException* 这个代码表示doSome()方法在执行过程中,有可能会出现ClassNotFoundException异常。* 叫做类没找到异常。这个异常直接父类是:Exception,所以ClassNotFoundException属于编译时异常。* @throws ClassNotFoundException*/public static void doSome() throws ClassNotFoundException{System.out.println("doSome!!!!");}
}

解决方法一、throws上报给方法调用者(推卸责任:调用者知道)

public class ExceptionTest04 {public static void main(String[] args) throws ClassNotFoundException {doSome();}public static void doSome() throws ClassNotFoundException{System.out.println("doSome!!!!");}
}

解决方法二、try…catch捕捉,处理(调用者是不知道)

public class ExceptionTest04 {public static void main(String[] args) {try {doSome();} catch (ClassNotFoundException e) {e.printStackTrace();}}public static void doSome() throws ClassNotFoundException{System.out.println("doSome!!!!");}
}

5、异常的处理方式

5.1 throws

在方法声明的位置上使用 throws 关键字抛出,谁调用我这个方法,我就抛给谁。抛给 调用者 来处理。

这种处理异常的态度:上报

5.2 try…catch

这个异常不会上报,自己把这个事儿处理了。
异常抛到此处为止,不再上抛了。

注意:

  • 只要异常没有捕捉,采用上报的方式,此方法的 后续代码不会执行
  • try语句块中的某一行出现异常,该行 后面的代码不会执行
  • try…catch捕捉异常之后,后续代码可以执行。

eg.

private static void m1() throws FileNotFoundException {System.out.println("m1 begin");m2();// 以上代码出异常,这里是无法执行的。System.out.println("m1 over");
}
try {m1();// m1方法出异常,下面代码不执行。System.out.println("hello world!");//不执行
} catch (FileNotFoundException e){ //异常处理System.out.println("出异常了!!");System.out.println(e); 
}
System.out.println("hello world"); //会执行

注意:

  • 异常发生之后,如果我选择了上抛,抛给了我的调用者,调用者需要对这个异常继续处理,那么调用者处理这个异常同样有两种处理方式。
  • 一般不建议在main方法上使用throws,因为这个异常如果真正的发生了,一定会抛给JVM。JVM只有终止。
  • 一般main方法中的异常建议使用try…catch进行捕捉。

注意:

try {} catch (ClassNotFoundException e) {e.printStackTrace();
}

这个分支中可以使用e引用,e引用 保存的内存地址是那个new出来 异常对象的内存地址


6、在以后开发中,处理编译时异常,应该上报还是捕捉呢?

  • 如果希望调用者来处理,选择throws上报。
  • 其它情况使用捕捉的方式。

7、深入try…catch

  1. catch后面的小括号中的类型可以是 具体的异常类型,也可以是该异常类型的 父类型
  2. catch可以写多个。建议catch的时候,精确的一个一个处理。这样有利于程序的调试。
  3. catch写多个的时候,从上到下,必须遵守 从小到大

eg.

try {FileInputStream fis = new FileInputStream("D:\\Download\\Javabean-addperson案例解析.docx");
} catch(FileNotFoundException e) {System.out.println("文件不存在!");
}等同于try {FileInputStream fis = new FileInputStream("D:\\Download\\Javabean-addperson案例解析.docx");
} catch(Exception e) {// 多态:Exception e = new FileNotFoundException();System.out.println("文件不存在!");
}
try {FileInputStream fis = new FileInputStream("D:\\Download\\Javabean-addperson案例解析.docx");fis.read();
} catch(IOException e){System.out.println("读文件报错了!");
} catch(FileNotFoundException e) {System.out.println("文件不存在!");
}
  1. JDK8的新特性:
    catch() 异常间可以自小到大| 分割

eg.

try {//创建输入流FileInputStream fis = new FileInputStream("D:\\Download\\Javabean-addperson案例解析.docx");// 进行数学运算System.out.println(100 / 0); // 这个异常是运行时异常,编写程序时可以处理,也可以不处理。
} catch(FileNotFoundException | ArithmeticException | NullPointerException e) {System.out.println("文件不存在?数学异常?空指针异常?都有可能!");
}

8、异常两个重要方法

方法名作用
String getMessage()返回异常的详细消息字符串
void printStackTrace()追踪堆栈异常信息(采用异步线程)

9、finally字句

在finally子句中的代码是最后执行的,并且是 一定会执行 的,即使try语句块中的代码出现了异常。

finally子句必须和try一起出现,不能单独编写。

9.1 finally语句通常使用在哪些情况下呢?

通常在finally语句块中完成 资源的释放/关闭

eg.

public class ExceptionTest10 {public static void main(String[] args) {FileInputStream fis = null; // 声明位置放到try外面。这样在finally中才能用。try {fis = new FileInputStream("D:\\Download\\Javabean-addperson案例解析.docx");String s = null;// 这里一定会出现空指针异常!s.toString();System.out.println("hello world!");// 流使用完需要关闭,因为流是占用资源的。// 即使以上程序出现异常,流也必须要关闭!// 放在这里有可能流关不了。//fis.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch(IOException e){e.printStackTrace();} catch(NullPointerException e) {e.printStackTrace();} finally {System.out.println("hello 浩克!");// 流的关闭放在这里比较保险。// finally中的代码是一定会执行的。// 即使try中出现了异常!if (fis != null) { // 避免空指针异常!try {// close()方法有异常,采用捕捉的方式。fis.close();} catch (IOException e) {e.printStackTrace();}}}}
}

9.2try和finally联用,没有catch

eg.

public class ExceptionTest11 {public static void main(String[] args) {try {System.out.println("try...");return;} finally {System.out.println("finally...");}// 这里不能写语句,因为这个代码是无法执行到的。//System.out.println("Hello World!");}
}

以下代码的执行顺序:

  1. 先执行try…
  2. 再执行finally…
  3. 最后执行 return (return语句只要执行方法必然结束。)

注意:

  • try不能单独使用。
  • try finally可以联合使用。
  • 放在finally语句块中的代码是一定会执行的

9.3 finally子句失效

System.exit(0); 只有这个可以治finally。

public class ExceptionTest12 {public static void main(String[] args) {try {System.out.println("try...");// 退出JVMSystem.exit(0); // 退出JVM之后,finally语句中的代码就不执行了!} finally {System.out.println("finally...");}}
}

9.4 finally面试题

public class ExceptionTest13 {public static void main(String[] args) {int result = m();System.out.println(result); //100}/*java语法规则(有一些规则是不能破坏的,一旦这么说了,就必须这么做!):java中有一条这样的规则:方法体中的代码必须遵循自上而下顺序依次逐行执行(亘古不变的语法!)java中海油一条语法规则:return语句一旦执行,整个方法必须结束(亘古不变的语法!)*/public static int m(){int i = 100;try {// 这行代码出现在int i = 100;的下面,所以最终结果必须是返回100// return语句还必须保证是最后执行的。一旦执行,整个方法结束。return i;} finally {i++;}}
}

反编译之后的效果:

public static int m(){int i = 100;int j = i;i++;return j;
}

9.5 final finally finalize有什么区别?

  • final 关键字
  1. final修饰的无法继承
  2. final修饰的方法无法覆盖
  3. final修饰的变量不能重新赋值
  • finally 关键字
  1. finally 和try一起联合使用。
  2. finally语句块中的代码是必须执行的。
  • finalize 标识符
  1. 是一个Object类中的方法名。
  2. 这个方法是由垃圾回收器GC负责调用的

10、自定义异常(开发中常用)

10.1前言

SUN提供的JDK内置的异常肯定是不够的用的。在实际的开发中,有很多业务,这些业务出现异常之后,JDK中都是没有的。和业务挂钩的。因此需要自定义异常。

10.2自定义异常步骤

  1. 第一步:编写一个类继承 Exception 或者 RuntimeException.
  2. 第二步:提供两个 构造方法,一个无参数的,一个带有String参数的。

eg.

//栈操作异常:自定义异常!
public class StackOperationException extends Exception{ // 编译时异常!public MyStackOperationException(){}public MyStackOperationException(String s){super(s);}
}

11、方法覆盖,时遗留的问题

  • 重写之后的方法不能比重写之前的方法抛出更多(更宽泛)的异常,可以更少。方法覆盖
class Animal {public void doSome(){}public void doOther() throws Exception{}
}class Cat extends Animal {// 编译正常。public void doSome() throws RuntimeException{}// 编译报错。/*public void doSome() throws Exception{}*/// 编译正常。/*public void doOther() {}*/// 编译正常。/*public void doOther() throws Exception{}*/// 编译正常。public void doOther() throws NullPointerException{}
}

注意:
一般不会这样考虑,方法覆盖复制一份,然后重写就好了。

12、总结异常中的关键字

  • 异常捕捉:
  1. try
  2. catch
  3. finally
  • throws 在方法声明位置上使用,表示上报异常信息调用者
  • throw 手动抛出异常

eg.

    public void pop() throws StackOperationException {if(index < 0){throw new MyStackOperationException("弹栈失败,栈已空!");//手动抛出异常}}

该方法index < 0时手动抛出异常,然后在方法里没有处理,上报给调用者,让调用者处理!


http://chatgpt.dhexx.cn/article/n8IxNLKO.shtml

相关文章

最全最详细的Java异常处理机制

一、异常概述与异常体系结构 异常概述 在使用计算机语言进行项目开发的过程中&#xff0c;即使程序员把代码写得尽善尽美&#xff0c;在系统的运行过程中仍然会遇到一些问题&#xff0c;因为很多问题不是靠代码能够避免的&#xff0c;比如&#xff1a;客户输入数据的格式&…

论文阅读_Heatmap解释

关节的热力图(Heatmap) 每一个关节点,生成一张热力图heatmap, 热力图的响应值作为关节位置的概率或似然. 热力图中数值越大的位置,响应值越大,表示越有可能是关节的位置. 那么构造heatmap实际上是构造了一个中间状态&#xff0c;这个heatmap有如下的一些优点&#xff1a; **1…

R绘图|heatmap

# 1.设置工作目录及调用R包 setwd("D://heatmap") library(vegan) library(RColorBrewer) library(gplots) library(permute) library(lattice)图1 原始数据文件格式。行名为样地名&#xff0c;列名为物种名。 # 2. 读入数据 dir() aoaread.csv("Aspe.csv"…

用Python绘制Heatmap

本文内容为基于python的heatmap的绘制与渲染 文章目录 前言一、Heatmap是什么&#xff1f;二、使用步骤1.引入库2.代码 总结 前言 在写论文时&#xff0c;看到大佬们的文章中精美的图表。却不知道如何进行绘制&#xff0c;本文提供了一种heatmap的绘制方式。 一、Heatmap是什么…

HeatMap(热图)的原理和实现

HeatMap&#xff08;热图&#xff09;的原理和实现 先来看两张图&#xff1a; &#xff08;1&#xff09;10年世界杯决赛&#xff0c;冠军西班牙队中门将、后卫、中场及前锋的跑位热图 通过热图&#xff0c;我们可以很清楚的看出四个球员在比赛中跑动位置的差异。 &#xff…

人体姿态估计-生成heatmap的方法

人体姿态估计-生成heatmap的方法 参考Simple BaseLine生成HeatMap的方法&#xff0c;这里整理进行显示&#xff0c;方便可视化&#xff1a; Simple BaseLine生成HeatMap的方法&#xff1a;human-pose-estimation.pytorch/JointsDataset.py at master microsoft/human-pose-es…

seaborn可视化——一文搞懂heatmap参数

文章目录 datacmaplinewidths、linecolorsquareaxannot指定为True指定为同形状数组 vmax、vminannot_kwsmaskxticklabels、yticklabels设置为auto指定整数指定为True centerrobustfmtcbar 数据使用的是seborn内置数据 官网链接&#xff1a;https://seaborn.pydata.org/generate…

BagNet特征heatmap可视化

BagNet地址&#xff1a;https://github.com/wielandbrendel/bag-of-local-features-models BagNet是ResNet的变体&#xff0c;显著的区别是将3x3卷积变为1x1卷积来达到构造整体网络具有某个最终的感受野(receptive field)目的。在这里主要讲解对于一张来源于ImageNet的尺寸为22…

关键点检测——heatmap热力图法

一、数据集格式 二、解析xml文件&#xff0c;生成data_center.txt from PIL import Image import math,os from xml.etree import ElementTree as ETdef keep_image_size_open(path, size(256, 256)):img Image.open(path)temp max(img.size)mask Image.new(RGB, (temp, te…

Learn OpenCV之Heatmap

本文是利用热图&#xff08;Heatmap&#xff09;分析视频序列的标定。 注意&#xff0c;这里目的不是标定而是分析标定好的数据&#xff0c;或者也可以是检测的结果数据 文章结构是这样的&#xff0c;先详细的解释一下热图分析有什么用&#xff0c;根据一些具体的应用实例给出…

python heatmap画法

任务描述 将一个归一化的分数以热图的形式显示出来&#xff0c;分数高的地方颜色深&#xff0c;分数小的地方颜色浅 注意&#xff1a;使用单一颜色无法实现这种渐变过程 原理 将单通道的0-1之间的score值映射到三通道的颜色空间 原料 一个单通道的score矩阵颜色空间列表&a…

python heatmap总结

基础使用 import seaborn as sns; sns.set_theme(color_codesTrue) iris sns.load_dataset("iris") species iris.pop("species") g sns.clustermap(iris)取消行列分类树 import seaborn as sns; sns.set_theme(color_codesTrue) import matplotlib.p…

seaborn绘制heatmap

【seaborn.heatmap整理】 用处&#xff1a;将数据绘制为颜色方格&#xff08;编码矩阵&#xff09;。 引用形式&#xff1a; seaborn.heatmap(data, vminNone, vmaxNone, cmapNone, centerNone, robustFalse, annotNone, fmt’.2g’, annot_kwsNone, linewidths0, linecolor‘…

Heatmap

前言 目前所说的模型可视化或者模型可解释说到是对某一类别具有可解释性&#xff0c;直接画出来特征图并不能说明模型学到了某种特征&#xff0c;对一个深层的卷积神经网络而言&#xff0c;通过多次卷积和池化以后&#xff0c;它的最后一层卷积层包含了最丰富的空间和语义信息…

R | 可视化 | 热图(Heatmap)

1 基础绘制 R绘制热图时&#xff0c;数据需要输入一个矩阵&#xff0c;可以用as.matrix()把它转换成矩阵。这里利用R自带的数据集绘制热图。 > # 数据 > data <- as.matrix(mtcars) > > # 绘制热图 > heatmap(data) OUTPUT: 热图的每一列是一个变量&…

科研作图-heatmap(一)

1.简介 在科研中有很多地方为了可解释给审稿人提供了热图,便于知道深度学习中到底是哪部分在起作用,或者是在机器学习中分析不同的特征之间是否存在相关性?存在多大的相关性;或者是直观的展示场景热力图…总之,用处很多,我正好现在也需要用,就先总结下:绘制HeatMap的库有很多,…

「C#」生成HeatMap(热度图)的实现

1、什么是Heatmap 其实不用多言&#xff0c;需要这个的人自然知道这是什么。基于一系列点生成的热度图&#xff0c;放张图感受一下&#xff1a; ma...大概就是这种样子。 2、生成&#xff08;计算&#xff09;原理 实现方式实际上是在每个点上叠加高斯矩阵。高斯矩阵就是在二…

关键点检测的heatmap介绍

开始学关键点检测的时候&#xff0c;到处找找不到heatmap的解释。现在大概有些懂了&#xff0c;干脆自己写一个。部分转载。 关键点定位任务两种做法&#xff1a;heatmap和fully connected回归&#xff08;Heapmap-based和Regression-Based&#xff09; heatmap得到一张类似热…

python绘制热度图(heatmap)

1、简单的代码 from matplotlib import pyplot as plt import seaborn as sns import numpy as np import pandas as pd#练习的数据&#xff1a; datanp.arange(25).reshape(5,5) datapd.DataFrame(data)#绘制热度图&#xff1a; plotsns.heatmap(data)plt.show() 查看效果&a…

热图(Heatmap)绘制(matplotlib与seaborn)

热图是数据统计中经常使用的一种数据表示方法&#xff0c;它能够直观地反映数据特征&#xff0c;查看数据总体情况&#xff0c;在诸多领域具有广泛应用。 一&#xff1a;matplotlib绘制方法 1.基础绘制 热图用以表示的是矩阵数据&#xff0c;例如相关阵、协差阵等方阵&#…