惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Threat Research - Cisco Blogs
Latest news
Latest news
Project Zero
Project Zero
TaoSecurity Blog
TaoSecurity Blog
Cyberwarzone
Cyberwarzone
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google DeepMind News
Google DeepMind News
P
Privacy & Cybersecurity Law Blog
T
Troy Hunt's Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
AWS News Blog
AWS News Blog
Hacker News: Ask HN
Hacker News: Ask HN
S
Security @ Cisco Blogs
C
Cisco Blogs
Help Net Security
Help Net Security
I
Intezer
W
WeLiveSecurity
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
腾讯CDC
S
Secure Thoughts
MyScale Blog
MyScale Blog
Recorded Future
Recorded Future
G
GRAHAM CLULEY
L
LINUX DO - 热门话题
A
About on SuperTechFans
C
CXSECURITY Database RSS Feed - CXSecurity.com
IT之家
IT之家
J
Java Code Geeks
The Hacker News
The Hacker News
阮一峰的网络日志
阮一峰的网络日志
Scott Helme
Scott Helme
Recent Announcements
Recent Announcements
AI
AI
Cisco Talos Blog
Cisco Talos Blog
B
Blog RSS Feed
V
Vulnerabilities – Threatpost
C
Check Point Blog
Security Latest
Security Latest
S
SegmentFault 最新的问题
T
The Exploit Database - CXSecurity.com
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
M
MIT News - Artificial intelligence
T
The Blog of Author Tim Ferriss
Attack and Defense Labs
Attack and Defense Labs
PCI Perspectives
PCI Perspectives
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
Tailwind CSS Blog
Apple Machine Learning Research
Apple Machine Learning Research

Moon's Blog

Java内存 | Moon's Blog Spring Data JPA | Moon's Blog Spring Boot的Java Config | Moon's Blog Java知识点 | Moon's Blog Spring Boot知识点 | Moon's Blog Java的类加载器 | Moon's Blog JVM类加载机制 | Moon's Blog 单体架构与微服务架构 | Moon's Blog 424.替换后的最长重复字符 | Moon's Blog 888.公平的糖果棒交换 | Moon's Blog 839.相似字符串组 | Moon's Blog 778.水位上升的泳池中游泳 | Moon's Blog 1631.最小体力消耗路径 | Moon's Blog 724.寻找数组的中心索引 | Moon's Blog 使用Jackson库实现日期序列化 | Moon's Blog 使用Jackson库实现Java多态解析 | Moon's Blog Spring Boot+InfluxDB实现日志管理 | Moon's Blog Java多态+工厂模式实现服务调用 | Moon's Blog 为Spring Boot项目生成OpenAPI3.0文档 | Moon's Blog
Java异常机制 | Moon's Blog
Moon Lou · 2021-03-12 · via Moon's Blog

Java异常机制,是程序运行不正常时的处理方式。具体来说,异常机制提供了程序安全退出的通道。当异常发生时,程序的执行流程改变,程序控制权转移到异常处理器

一、Java异常继承体系

Java异常类的继承体系如下图所示:

Throwable类是整个Java异常体系的超类,包括错误Error和异常Exception两个子类。

  • Error表示程序在运行期间出现了十分严重、不可恢复的错误,这种情况下应用程序只能终止运行,比如JVM出现错误(VirtualMachineError)。应用程序一般不捕获Error,因为它是应用程序所无法处理的情况。
  • Exception是应用程序可以处理的异常,可以选择对其进行捕获并处理,包含运行时异常(RuntimeException)非运行时异常(除RuntimeException外的其他异常)
    • 运行时异常RuntimeException是在程序运行时出现的异常,一般是由程序的逻辑错误所引起的,可以选择捕获处理,也可以不捕获处理。比如NullPointerException、IndexOutOfBoundsException等。
    • 非运行时异常也叫受检异常必须在应用程序中对其进行捕获处理或者向上抛出,否则无法通过编译器检查。比如IOException、ClassNotFoundException等。方法内部如果抛出了受检异常,则必须在方法头部声明抛出该受检异常类型。

用户可以在在Java异常体系的基础上自定义类异常类型,自定义异常类型要遵循以下原则:

  • 自定义异常类必须是Throwable的子类。
  • 如果想自定义一个受检异常类,需要继承Exception类
  • 如果想自定义一个运行时异常类,需要继承RuntimeException类

二、异常的抛出与捕获处理

1.异常抛出(throw、throws)

throw关键字用于方法体内部,用来抛出异常。如果抛出的是一个受检异常,那么还应该在方法头部用throws声明抛出的受检异常类型,该方法的调用者也必须捕获处理或者向上抛出这个受检异常。比如:

public class className {
public void deposit(double amount) throws RemoteException {

throw new RemoteException();
}

}

2.异常捕获处理(try…catch…finally)

try代码块中某位置抛出了异常,则该位置之后的代码再也没有机会被执行。

catch可以有多个,一个try代码块后面跟随多个catch代码块的情况叫多重捕获,根据异常的类型从上往下匹配,如果有匹配的catch,下面的所有catch会被全部忽略。

多重捕获下要先catch子类异常再catch父类异常,即子类异常的catch块在父类异常catch块的上面。如果顺序反了的话,那么根据Java继承思想,所有子类异常对象都是父类异常对象,导致父类异常永远先被捕获到,而捕获子类异常的catch块永远得不到执行,出现编译错误。比如下面的代码:(ArithmeticException是Exception的子类,属于受检异常)

public class ExceptionErrorDemo {
public static void main(String[] args) {
int[] numbers = new int[3];
try {
numbers[0] = 1;
numbers[1] = 3;
numbers[2] = 7;
numbers[3] = numbers[2] / 0;
} catch (Exception e) {
System.out.println(e.toString());
} catch (ArithmeticException e) {
e.toString();
}
}
}

无论try代码块中是否发生异常,finally代码块都会被执行。通常可以在finally块中进行资源的回收工作,比如关闭打开的文件、删除临时文件等。

如果try、catch块中有return语句,会先把返回值压栈,然后再执行finally语句,执行完finally语句后再返回。即使在finally中更改了要返回的变量的值,程序依然会返回之前已经压栈的值,而不是在finally中更新后的值。当然,如果try、catch中返回的变量是一个对象引用而非基本类型,由于引用已经压栈无法更改,可以通过在finally块中更改引用指向的对象的内容,来影响返回结果。如果finally中有return语句,那么直接忽略try、catch中的return语句,只执行finally的return

版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Moon's Blog