Java基础(四):异常处理
思维导图:
一、异常的分类
1. 编译时期异常
直接父类为 Exception 则为编译时期异常。
编译时期异常需要在编译阶段进行处理,否则编译器报错,如果不处理,则无法执行代码,如下:
public class XKException {static void Test() {ExceptionTest();// 报错:Unhandled exception: java.lang.ClassNotFoundException}static void ExceptionTest () throws ClassNotFoundException {ClassNotFoundException exception = new ClassNotFoundException("出事啦!!!");throw exception;}
}
结果:
2. 运行时期异常
直接父类为 RuntimeException 时,表示运行时期异常;
运行时异常在编译时期不处理,但是在运行时则会 crash:
RuntimeException 的父类也是 Exception
二、异常处理
异常必须进行处理,否则在编译时期就会报错,或者在运行时 crash,一般有几种方式:
- 上抛;
- try catch;
完整的处理流程如下:
1. 上抛
处理方式:在函数声明后面加上 @throws xxxException;
原理:此种处理方式会将异常按照函数的调用者层级向上抛,如果抛到 main 函数还没有处理,最终会抛给 JVM,JVM 会终止程序;
public class XKExceptionTest {// main函数继续上报Exception给JVMpublic static void main(String[] args) throws ClassNotFoundException {XKExceptionTest.Test();}// 上报Exceptionstatic void Test() throws ClassNotFoundException {ClassNotFoundException exception = new ClassNotFoundException();throw exception;}
}
因为 main 函数依旧没有处理 exception,所以最终会抛给 JVM,在运行时 crash:
但是有个注意点:
- 子类不能比父类抛出更多的异常;
例子:
上述代码会报错:
如上代码,Runnable 接口中的 run 方法并没有抛出异常,子类实现 runnable 接口的 run 方法时,不能抛出异常;而 sleep 方法是有可能出现异常的:
因此,只能使用 try catch 进行捕捉;
2. try catch
处理方式:对于有 throws 的函数,在 try 语句中进行函数调用并使用 catch 捕捉异常并处理;
上述代码可以写成:
3. try catch 的几个特点
- try 中语句检测到异常时,那一行代码之后的代码不会运行,但是不影响 try catch 整体之后的代码运行;
- 如果 try 中的代码存在多个异常需要处理,那么都需要在 catch 中处理;
- 多个异常的处理有两种方案,一个是或符号,一个是多个 catch;
- catch 中的错误类型可以是多态形式,但是要确保所有的类型都被处理到;
示例:
另外,如果对异常的处理比较统一,可以在 catch 中使用 Exception 来拦截所有的异常情况,不需要或符号或者多个 catch 了:
4. finally
不管怎样都会执行,其含义包括:
- try 中代码没有报异常;
- try 代码出现了异常;
作用:出错或者不出错都需要执行的操作,比如 I/O 流的关闭:
public class XKException {static void Test() {FileInputStream fileStream = null;try {fileStream = new FileInputStream("x//xxxx/xxx");} catch (FileNotFoundException e) {System.out.println("文件未找到");} finally {// 不管是否出错,I/O流都需要关闭if (fileStream != null) {try {// 可能会出现IOException异常,需要处理fileStream.close();} catch (IOException e) {e.printStackTrace();}}}}
}
即使 try 中 retrun 了,finally 中的代码也会执行:
try {System.out.println("xxx");return;
} finally {System.out.println("这里的代码仍然会执行");
}
System.out.println("这里的代码不会执行"); // 编译报错
其本质是走到 return 时会先去检测 finally 中是否有代码,如果有就先执行再 return;
退出 JVM 时 finally 不会执行:
try {System.out.println("try");System.exit(0);
} finally {System.out.println("退出JVM后finally中的代码不执行");
}
虽然 finally 中的代码在 return 之前执行,但是返回值不会被改变,因为 Java 中所有代码都需要遵循两条规则:
- 顺序执行
- return 一旦执行,方法必须立即结束;
例子:
static void Test() {int i = FinallyTest();System.out.println("方法的返回值为:" + i); //100
}static int FinallyTest() {int a = 100;try {return a;} finally {a++;System.out.println("finally中的a为:" + a); //101}
}
反编译之后的结果:
int a = 100;
int j = a;
j++;
return j;
结果:
finally中的a为:101
方法的返回值为:100
这里和 OC 中的原理差不多,相当于 finally 中对变量进行了引用或者赋值。这也是为什么 finally 中可能出现内存泄漏的原因;
三、final、finally、finalize 对比
final
- 关键字;
- 修饰变量时存储在常量区,表示只能在初始化时赋值;
- 修饰成员属性时,表示只能在构造函数中初始化,或者声明时初始化。此时视情况而定,最好加上 static,否则多个实例变量会占用多块内存;
- final 修饰类时,该类不能被继承,比如系统类 String;
- final 修饰方法是,子类无法重写该方法,但是不影响该方法重载;
finally
- 和 try catch 一起使用;
- finally 中的代码无论是否异常都会执行;
- 如果 try 中有 return,finally 的代码在 return 之前执行,但是不影响返回值的结果,因为 finally 内部对使用到的变量进行了捕捉,非引用类型重新赋值一个新的变量,引用类型进行深拷贝,即重新复制了一个实例对象;
- OC 中 finally 存在内存泄漏的风险;
对比 const 回顾:
- 不改变生命周期;
- 不改变作用域;
- 只表示被修饰的部分不可变,且只修饰变量,其他关键字不会影响,比如 static、变量类型等;
- 如果是非指针类型,则单纯的表示变量的值不可变;
- 如果是指针类型,修饰 const * xxx 时表示变量所指向的对象不可变;
- 如果是指针类型,修饰 * const xxx 时表示
四、自定义Exception
按照国际惯例,自定义的异常应该总是包含如下的构造函数:
- 一个无参构造函数
- 一个带有String参数的构造函数,并传递给父类的构造函数。
- 一个带有String参数和Throwable参数,并都传递给父类构造函数
- 一个带有Throwable 参数的构造函数,并传递给父类的构造函数。
下面是IOException类的完整源代码,可以借鉴:
package java.io;public class IOException extends Exception {static final long serialVersionUID = 7818375828146090155L;public IOException() {super();}public IOException(String message) {super(message);}public IOException(String message, Throwable cause) {super(message, cause);}public IOException(Throwable cause) {super(cause);}
http://www.taodudu.cc/news/show-1912749.html
相关文章:
- Java基础(五):多线程
- Android:权限处理
- AsyncTask的基本使用
- 在Nginx中配置SSL证书
- Base64编码流程
- Nginx配置基础认证
- Cookie、Session、Token、RefreshToken
- JSCore浅析及其在iOS上的使用
- 编程语言的动态性(Dart和OC对比)
- iOS:Universal Link
- AFN中的鉴权
- openGL ES 教程(二):渲染管线
- MySQL(2)----DDL语句之增、删、改、查操作
- MySQL(3)-----DML数据库操作(上)
- 线性表的基本运算
- MySQL(4)-----DML数据库操作(下)
- MySQL(1)----帮助使用
- MySQL(6)-----数据类型
- (1)封装JSON数据的三种方式
- (2)从文件中解析JSON数据
- (1)I/O流对象-----FileInputStream与FileOutputStream
- MyBatis(一)------目录
- MyBatis(二)------使用JDBC编程问题总结
- MySQL(5)-----DQL语句的基本查询与高级查询
- MySQL(7)-----常用约束
- MySQL(8)-----truncate清空表和字段自增
- MySQL(9)-----多表创建及描述表关系(需求)
- (1)Spring框架----通俗易懂的IoC原理
- MySQL(10)-----多表创建及描述表关系(一对多的分析和实现)
- MySQL(11)-----多表创建及描述表关系(多对多的分析和实现)
Java基础(四):异常处理相关推荐
- java实验四结果,java实验四异常处理.doc
java实验四异常处理.doc 实验四异常处理一.实验目的1.掌握异常的概念和Java异常处理机制.2.掌握异常的定义.抛出和捕捉处理.二.实验内容与要求1.仔细读下面的JAVA语言源程序,自己给出程 ...
- 【Java基础】异常处理与输入输出流
finally中的代码执行时机 try{}语句中含有return,那么finally还会执行吗?如果会,那么是什么时候执行(return前还是return后) 在Java的异常处理中,不论什么情形,f ...
- 《温故而知新》JAVA基础四
类的封装 定义:将类的一些信息隐藏起来,不允许外部的程序直接的访问,而是通过该类提供的一些方法来获取 好处:只能通过特定的法方法访问数据,保护了数据, 实现封装的步骤: 修改属性的可见性:(一般类属性 ...
- java 基础(异常处理)
<pre name="code" class="java">/*异常:就是程序在运行时出现的不正常情况.异常的由来:问题也就是现实生活中的一个具体事 ...
- Java基础四——面向对象思想
1.1 什么是面向对象 面向对象思想就是不断的创建对象(属性与行为的封装,让二者作为整体参与程序执行),使用对象,指挥对象做事情.(在已有对象的情况下,直接使用对象,而不再去考虑对象的内部构造) 面向 ...
- Java基础-四要素之一《封装》
封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保 ...
- java基础(四) java运算顺序的深入解析
1. 从左往右的计算顺序 与C/C++不同的是,在Java中,表达式的计算与结果是确定的,不受硬件与环境的影响.如: int i = 5; int j = (i++) + (i++) +(i++) ...
- 【4】 Java基础 四
构造方法,可以有多个. 1 public class phone { 2 //属性 3 private String name = "华为"; 4 5 6 //方法 或者叫函数 7 ...
- Java基础知识——异常处理
目录 异常概述 异常体系结构 异常的分类 常见异常举例 异常处理方式 方式一:try-catch-finally finally的使用 方式二:throws 手动抛出异常 自定义异常 异常 ...
- 一文带你深入理解【Java基础】· 枚举类
写在前面 Hello大家好, 我是[麟-小白],一位软件工程专业的学生,喜好计算机知识.希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正!谢谢大家!!! ...
最新文章
- 杨强 : 迁移学习——人工智能的最后一公里
- 怎么设置matlab滑块的值,matlab - 如何根据另一个滑块更改滑块的最大值 - SO中文参考 - www.soinside.com...
- Unity应用架构设计(7)——IoC工厂理念先行
- POJ1364基本的查分约束问题
- JZOJ 100046. 【NOIP2017提高A组模拟7.14】收集卡片
- MFC使用OpenCV在文档窗口中显示图像(支持多图片格式)
- yarn 常用命令(干干货!)
- 使用JMH做Java微基准测试(四)默认状态测试
- 捷顺USB-RS485驱动
- ST-Link驱动安装不正确,设备管理器黄色感叹号,win10安装stlink驱动
- Python文件转换为exe文件,可执行文件方法
- SNE T分布 t-SNE数据降维与可视化
- Android截屏截图方法所有方法汇总(包括Activity、View、ScrollView、ListView、RecycleView、WebView截屏截图)
- es---elasticsearch-篇二:idea操作es,常用查询DSL
- vue js 汉字转拼音
- 小程序分享,禁用分享,解除禁用分享
- SM2262EN+东芝BICS3 1TB开卡报错处理
- 3GPP协议 25.105
- MySQL快速插入亿级数据
- 预处理对象executeQuery方法,对数据库进行有条件和无条件的查询