[Java学习笔记] Java异常机制(也许是全网最独特视角)
Java 异常机制(也许是全网最独特视角)
一、Java中的“异常“指什么
什么是异常
一句话简单理解:异常是程序运行中的一些异常或者错误。
(纯字面意思)
Error类 和 Exception类
Java中“万物皆对象”,异常也不例外,
Java把异常当做对象来处理,并将异常分为两大类——Error(错误)和Exception(异常),它们都是Throwable类的子类。
这里看起来可能有点奇怪,什么叫“把异常分为错误和异常两类”??可以这样粗暴地理解——异常有两大类,一类是错误异常(Error),另一类是异常异常(Exception)。
至于为什么这么奇怪,我觉得既有翻译的问题,也有Java文档没说清楚的问题。(主要是翻译的锅)
Oracle的JavaSE官方文档是这样说的:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.
The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.
所以个人见解,我们可以把Throwable这个类翻译为“事故类 ”(单词problem:问题、状况、事故),这个“事故类”的对象具有可被抛出的性质,且”事故类“Throwable有两个子类“错误事故”(Error,对应致命的大事故)和"异常事故"(Exception,对应剩余可以处理的事故)。
所以Java的“异常机制”这个翻译很容易误导人,让人奇怪什么叫异常包括错误和异常,EXception的异常和“异常机制”的异常,这两个翻译冲突了,所以我认为更应该翻译为Java的“事故机制”。
Error类的常见子类有IOError、AWTError、VirtualMachineError等,
Exception类的常见子类有IOException、RuntimeException等。
Error和Exception的区别
Error通常是灾难性的致命错误,是程序无法控制和处理的,当出现这类异常时,JVM一般会选择终止线程;而Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这类异常。
个人总结:曾经纠结Error和Exception的区别纠结了好久,后来发现根本不用纠结,就当成一样的东西就好了,都是“意外状况”,只不过一个严重点一个不严重点而已。由于Error是严重的异常,对于程序已经致命了,所以并不需要捕获(catch)或者声明(throws),而Exception属于不那么严重,还可以“挽救”或者说“预判”的异常,所以可以被捕获(catch)或者声明(throws)来做出进一步处理。
二、异常的捕获和抛出
异常处理的五个关键字——try、catch、finally、throw、throws。
try 和 catch 关键字可以捕获异常。
try/catch 代码块放在异常可能发生的地方,try 代码块中的代码会先被执行,catch 语句包含要捕获异常类型的声明。当 try 语句中的代码发生一个异常时,try 后面的 catch 块就会被检查,如果发生的异常是catch语句所声明的异常类型的实例,则该异常会被传递到该 catch 块并执行catch代码块中的代码,类似于传递一个参数到方法中。
finally代码块出现在catch代码块之后,无论try代码块中是否发生异常,finally代码块中的代码总会被执行。
注意:1、try代码块后必须有catch代码块或者finally代码块;
2、靠上的catch所声明的异常类型不能是靠下的catc所声明的异常类型的父类(如以下代码中,e1不是e2的父类)。
try{
//正常执行的代码
}catch(Exception1 e1){
//捕获到Exception1类的异常后执行的代码
//捕获到的异常被赋值给e1
}catch(Exception2 e2){
//捕获到Exception2类的异常后执行的代码
//捕获到的异常被赋值给e2
}finally{
//善后代码
}
throw 和 throws 关键字用于主动抛出异常。
两个关键字的区别是,throw用于抛出一个异常,而throws用于声明方法可能抛出的异常。
throw只能抛出一个异常对象,throws可以声明多个可能发生的异常类。
即一个负责抛出,一个负责声明。
注意:1、若方法中有 异常(严格来说是检查异常,详见后文)抛出,必须使用throws语句在方法头处声明异常,或者在方法体内使用try/catch语句将异常抛出语句包围(将throw语句置于try代码块中);
2、若一个方法使用了throws语句声明异常,则引用此方法的另一个方法必须使用throws语句在方法头处声明异常,或者使用try/catch语句将引用此方法的语句包围(将引用此方法的语句置于try代码块中)
public void test1(){
//使用try/catch语句处理异常
try{
throw new Exception();
}catch(Exception e){
System.out.println("Thers's an exception.")
}
} public void test2() throws Exception{
//使用throws语句在方法头处声明异常
throw new Exception();
} public void test3() throws Exception{
//引用test2也要声明异常
test2();
} public void test4() throws Exception{
//引用test2也要声明异常总结:可以这样理解,throw就是抛出异常,try/catch就是处理异常,throws就是暂时不处理、交给引用自己的方法处理。
检查异常(checked exception)和非检查异常(unchecked exception)
检查异常:除了Error类及其子类 和 RuntimeException类及其子类,其它的Throwable子类都是检查异常。
非检查异常:Error类及其子类 和 RuntimeException类及其子类。
检查异常是编译器要求程序必须处置的异常,这种异常的特点是Java编译器会检查它是否被捕获(try/catch)或者声明(throws),否则编译不通过。非检查异常是编译器不要求强制处理的异常。
public viod test(){
//抛出Error类对象但并不做处理,编译也能通过。
throw new Error();
}
public viod test(){
//抛出RuntimeException类对象但并不做处理,编译也能通过。
throw new RuntimeException();
}
//Error类及其子类 和 RuntimeException类及其子类 都是非检查异常,
运行时异常和非运行时异常
运行时异常:RuntimeException类及其子类。
非运行时异常:RuntimeException以外的Exception类及其子类。
其实运行时异常就是 除去Error类的非检查异常,
如果我们不去处理运行时异常,JVM会接管处理,系统会把异常一直往上层抛,一直到最上层,
最上层抛出之后,如果抛出异常在线程中,这个线程就会退出,如果抛出异常在主程序中,整个程序就退出了。
也就是说,如果不对运行时异常进行处理,程序会通过编译并运行,出现运行时异常后,要么是线程终止,要么是主程序终止。
public class Draft {
public static void test1(){
throw new RuntimeException();
}
public static void test2(){
test1();
}
public static void main(String[] args) {
test2();
}
}
运行以上代码,终端会出现以下结果,
Exception in thread "main" java.lang.RuntimeException
at Draft.test1(Draft.java:3)
at Draft.test2(Draft.java:6)
at Draft.main(Draft.java:9)
三、自定义异常
- 如果Java提供的内置异常类型不能满足程序设计的需求,我们可以自定义异常类,只需要继承Exception类或者它的子类,以上异常机制对自定义的异常类同样适用。
呼,终于写完咯!人生第一篇博客,欢迎各路大佬指正!
此后会持续更新学习笔记,每一篇都会用心去写去感悟。
[Java学习笔记] Java异常机制(也许是全网最独特视角)的更多相关文章
- 1.13(java学习笔记)异常机制
异常不同于错误,它是程序运行时产生的未知问题. 如果把程序比喻成一辆汽车,那么汽车开着开着突然前面出现了一个大石头挡住了路,这就叫异常. 那么出现了这个异常我们需要去处理,比如打电话给公路管理局,让它 ...
- Java学习笔记__异常机制_try_catch_finally_return执行顺序
package cn.xiaocangtian.Exception; import java.io.FileInputStream; import java.io.FileNotFoundExcept ...
- java学习笔记09--反射机制
java学习笔记09--反射机制 什么是反射: 反射是java语言的一个特性,它允许程序在运行时来进行自我检查并且对内部的成员进行操作.例如它允许一个java的类获取他所有的成员变量和方法并且显示出来 ...
- [java学习笔记]java语言核心----面向对象之this关键字
一.this关键字 体现:当成员变量和函数的局部变量重名时,可以使用this关键字来区别:在构造函数中调用其它构造函数 原理: 代表的是当前对象. this就是所在函数 ...
- [java学习笔记]java语言核心----面向对象之构造函数
1.构造函数概念 特点: 函数名与类名相同 不用定义返回值类型 没有具体的返回值 作用: 给对象进行初始化 注意: 默认构造函数 多个构造函数是以重载出现的 一个类中如果 ...
- java学习笔记13--反射机制与动态代理
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note13.html,转载请注明源地址. Java的反射机制 在Java运行时环境中,对于任意 ...
- 【原】Java学习笔记030 - 异常
package cn.temptation; public class Sample01 { public static void main(String[] args) { /* * 异常:Java ...
- Java学习笔记 -- Java定时调度工具Timer类
1 关于 (时间宝贵的小姐姐请跳过) 本教程是基于Java定时任务调度工具详解之Timer篇的学习笔记. 什么是定时任务调度 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务. 在Ja ...
- 我的Java学习笔记-Java面向对象
今天来学习Java的面向对象特性,由于与C#的面向对象类似,不需详细学习 一.Java继承 继承可以使用 extends 和 implements 这两个关键字来实现继承. extends:类的继承是 ...
随机推荐
- SpringBoot程序预装载数据
简介 在项目实际的开发过程中,有时候会遇到需要在应用程序启动完毕对外提供服务之前预先将部分数据装载到缓存的需求.本文就总结了常见的数据预装载方式及其实践. 适用场景 预装载应用级别数据到缓存:如字典数 ...
- asp.net swagger的使用
最近要从其他系统获取一些数据,准备写个接口让别人把数据塞进来,顺便学习一下如何使用Swagger. 参考大神的教程:asp.net https://mp.weixin.qq.com/s/SHNNQo ...
- WinUI迁移到即将"过时"的.NET MAUI个人体验
迁移的初衷 本人平时是做.net相关的工作,对于.net技术栈也有一些了解,自从新的.net能够跨平台之后,之前也有跨平台的ui框架Xamarin,现在微软推出了.NET MAUI这个说是 统一了开发 ...
- mysql二进制日志和mysql备份工具介绍以及日志恢复
mysql备份: 三种备份方式 冷备:数据库停机,在进行备份 热备:lock table锁表,read 数据库只可以读不能写,在备份 温备:备份时数据库正常运行 备份类型:完整备份:全部备份,部分 ...
- 零基础学Java第五节(面向对象一)
本篇文章是<零基础学Java>专栏的第五篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 本文章首发于公众号[编程攻略] 类与对象 在哲学体系中,可以分为主 ...
- pandas:数据迭代、函数应用
1.数据迭代 1.1 迭代行 (1)df.iterrows() for index, row in df[0:5].iterrows(): #需要两个变量承接数据 print(row) print(& ...
- 三面阿里,被Java面试官虐哭!现场还原真实的“被虐”场景
前言 人人都有大厂梦,我也不例外,从大三开始,就一直想进入阿里工作,大毕竟是大厂,想想也没那么容易,不过好在自己学历还过得去,项目经验也有得讲,所以今年也斗胆尝试了一下,直接就投了阿里云计算.简历是过 ...
- Spring Ioc源码分析系列--容器实例化Bean的四种方法
Spring Ioc源码分析系列--实例化Bean的几种方法 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到bean真正通过那些方式实例化出来的时候,并没有继续分 ...
- 线程安全性-原子性之synchronized锁
原子性提供了互斥访问:同一时刻只能有一个线程进行操作: 除了Atomic包类之外,还有锁可以实现此功能: synchronized: java关键字,依赖于jvm实现锁功能,被此关键字所修饰的,都是 ...
- c++ 超大整数除法 高精度除法
c++ 超大整数除法 高精度除法 解题思路 计算a/b,其中a为大整数,b为普通整数,商为c,余数为r. 根据手算除法的规则,上一步的余数记为r,则本次计算的被除数为t=r*10+被除数的本位数值a[ ...