思维导图:

异常处理.png

一、异常的分类

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,一般有几种方式:

  1. 上抛;
  2. 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:

JVM终止程序

但是有个注意点:

  • 子类不能比父类抛出更多的异常;

例子:

sleep方法

上述代码会报错:

子类不能比父类抛出更多异常

如上代码,Runnable 接口中的 run 方法并没有抛出异常,子类实现 runnable 接口的 run 方法时,不能抛出异常;而 sleep 方法是有可能出现异常的:

sleep方法

因此,只能使用 try catch 进行捕捉;

2. try catch

处理方式:对于有 throws 的函数,在 try 语句中进行函数调用并使用 catch 捕捉异常并处理;

上述代码可以写成:

try catch

3. try catch 的几个特点

  1. try 中语句检测到异常时,那一行代码之后的代码不会运行,但是不影响 try catch 整体之后的代码运行;
  2. 如果 try 中的代码存在多个异常需要处理,那么都需要在 catch 中处理;
  3. 多个异常的处理有两种方案,一个是或符号,一个是多个 catch;
  4. catch 中的错误类型可以是多态形式,但是要确保所有的类型都被处理到;

示例:

多exception处理

另外,如果对异常的处理比较统一,可以在 catch 中使用 Exception 来拦截所有的异常情况,不需要或符号或者多个 catch 了:

拦截所有exception

4. finally

不管怎样都会执行,其含义包括:

  1. try 中代码没有报异常;
  2. 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

  1. 关键字;
  2. 修饰变量时存储在常量区,表示只能在初始化时赋值;
  3. 修饰成员属性时,表示只能在构造函数中初始化,或者声明时初始化。此时视情况而定,最好加上 static,否则多个实例变量会占用多块内存;
  4. final 修饰类时,该类不能被继承,比如系统类 String;
  5. final 修饰方法是,子类无法重写该方法,但是不影响该方法重载;

finally

  1. 和 try catch 一起使用;
  2. finally 中的代码无论是否异常都会执行;
  3. 如果 try 中有 return,finally 的代码在 return 之前执行,但是不影响返回值的结果,因为 finally 内部对使用到的变量进行了捕捉,非引用类型重新赋值一个新的变量,引用类型进行深拷贝,即重新复制了一个实例对象;
  4. OC 中 finally 存在内存泄漏的风险;

对比 const 回顾:

  1. 不改变生命周期;
  2. 不改变作用域;
  3. 只表示被修饰的部分不可变,且只修饰变量,其他关键字不会影响,比如 static、变量类型等;
  4. 如果是非指针类型,则单纯的表示变量的值不可变;
  5. 如果是指针类型,修饰 const * xxx 时表示变量所指向的对象不可变;
  6. 如果是指针类型,修饰 * const xxx 时表示

四、自定义Exception

按照国际惯例,自定义的异常应该总是包含如下的构造函数:

  1. 一个无参构造函数
  2. 一个带有String参数的构造函数,并传递给父类的构造函数。
  3. 一个带有String参数和Throwable参数,并都传递给父类构造函数
  4. 一个带有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基础(四):异常处理相关推荐

  1. java实验四结果,java实验四异常处理.doc

    java实验四异常处理.doc 实验四异常处理一.实验目的1.掌握异常的概念和Java异常处理机制.2.掌握异常的定义.抛出和捕捉处理.二.实验内容与要求1.仔细读下面的JAVA语言源程序,自己给出程 ...

  2. 【Java基础】异常处理与输入输出流

    finally中的代码执行时机 try{}语句中含有return,那么finally还会执行吗?如果会,那么是什么时候执行(return前还是return后) 在Java的异常处理中,不论什么情形,f ...

  3. 《温故而知新》JAVA基础四

    类的封装 定义:将类的一些信息隐藏起来,不允许外部的程序直接的访问,而是通过该类提供的一些方法来获取 好处:只能通过特定的法方法访问数据,保护了数据, 实现封装的步骤: 修改属性的可见性:(一般类属性 ...

  4. java 基础(异常处理)

    <pre name="code" class="java">/*异常:就是程序在运行时出现的不正常情况.异常的由来:问题也就是现实生活中的一个具体事 ...

  5. Java基础四——面向对象思想

    1.1 什么是面向对象 面向对象思想就是不断的创建对象(属性与行为的封装,让二者作为整体参与程序执行),使用对象,指挥对象做事情.(在已有对象的情况下,直接使用对象,而不再去考虑对象的内部构造) 面向 ...

  6. Java基础-四要素之一《封装》

    封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保 ...

  7. java基础(四) java运算顺序的深入解析

    1. 从左往右的计算顺序   与C/C++不同的是,在Java中,表达式的计算与结果是确定的,不受硬件与环境的影响.如: int i = 5; int j = (i++) + (i++) +(i++) ...

  8. 【4】 Java基础 四

    构造方法,可以有多个. 1 public class phone { 2 //属性 3 private String name = "华为"; 4 5 6 //方法 或者叫函数 7 ...

  9. Java基础知识——异常处理

    目录 异常概述 异常体系结构 异常的分类 ​ 常见异常举例 ​ ​ 异常处理方式 方式一:try-catch-finally finally的使用 方式二:throws 手动抛出异常 自定义异常 异常 ...

  10. 一文带你深入理解【Java基础】· 枚举类

    写在前面 Hello大家好, 我是[麟-小白],一位软件工程专业的学生,喜好计算机知识.希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正!谢谢大家!!! ...

最新文章

  1. 杨强 : 迁移学习——人工智能的最后一公里
  2. 怎么设置matlab滑块的值,matlab - 如何根据另一个滑块更改滑块的最大值 - SO中文参考 - www.soinside.com...
  3. Unity应用架构设计(7)——IoC工厂理念先行
  4. POJ1364基本的查分约束问题
  5. JZOJ 100046. 【NOIP2017提高A组模拟7.14】收集卡片
  6. MFC使用OpenCV在文档窗口中显示图像(支持多图片格式)
  7. yarn 常用命令(干干货!)
  8. 使用JMH做Java微基准测试(四)默认状态测试
  9. 捷顺USB-RS485驱动
  10. ST-Link驱动安装不正确,设备管理器黄色感叹号,win10安装stlink驱动
  11. Python文件转换为exe文件,可执行文件方法
  12. SNE T分布 t-SNE数据降维与可视化
  13. Android截屏截图方法所有方法汇总(包括Activity、View、ScrollView、ListView、RecycleView、WebView截屏截图)
  14. es---elasticsearch-篇二:idea操作es,常用查询DSL
  15. vue js 汉字转拼音
  16. 小程序分享,禁用分享,解除禁用分享
  17. SM2262EN+东芝BICS3 1TB开卡报错处理
  18. 3GPP协议 25.105
  19. MySQL快速插入亿级数据
  20. 预处理对象executeQuery方法,对数据库进行有条件和无条件的查询

热门文章

  1. mybatis-plus更新问题 全量更新、只更新部分属性
  2. 【Shiro第八篇】SpringBoot + Shiro使用Shiro标签
  3. Java线程 生产者--消费者模式总结(一)
  4. 数据库悲观锁和乐观锁
  5. 高可用分布式非关系型数据库-Cassandra
  6. 机器学习会成为2017年大数据​分析的瓦解者吗?
  7. 31、Arrays数组排序(续)——自定义排序
  8. 人人都是 DBA(II)SQL Server 元数据 (转)
  9. Visual Studio使用技巧---(1-10)
  10. BZOJ3038 上帝造题的七分钟2