Java异常目录:

  • 1.异常定义
  • 2.异常的用法
    • 2.1捕获异常
    • 2.2 调用栈 定义
    • 2.3 其他一些注意事项
  • 3.异常处理流程
  • 4. 抛出异常
  • 5.异常说明
  • 6. Java 异常体系
  • 7.自定义异常类
  • 8. 结尾

1.异常定义

所谓异常指的就是程序在 运行时 出现错误时通知调用者的一种机制.

关键字 “运行时”

有些错误是这样的, 例如将 System.out.println 拼写错了, 写成了 system.out.println. 此时编译过程中就会出错, 这是 “编译期” 出错.

而运行时指的是程序已经编译通过得到 class 文件了, 再由 JVM 执行过程中出现的错误.

异常的种类有很多, 不同种类的异常具有不同的含义, 也有不同的处理方式.

2.异常的用法

2.1捕获异常

基本语法:

try{
有可能出现异常的语句 ;
}[catch (异常类型 异常对象) {} ... ]
[finally {异常的出口
}]
  • try 代码块中放的是可能出现异常的代码.
  • catch 代码块中放的是出现异常后的处理行为.
  • finally 代码块中的代码用于处理善后工作, 会在最后执行.
  • 其中 catch 和 finally 都可以根据情况选择加或者不加.

列如 : 处理一个数组越界的异常

关于异常的处理方式

异常的种类有很多, 我们要根据不同的业务场景来决定.
对于比较严重的问题(例如和算钱相关的场景), 应该让程序直接崩溃, 防止造成更严重的后果
对于不太严重的问题(大多数场景), 可以记录错误日志, 并通过监控报警程序及时通知程序猿
对于可能会恢复的问题(和网络相关的场景), 可以尝试进行重试.
在我们当前的代码中采取的是经过简化的第二种方式. 我们记录的错误日志是出现异常的方法调用信息, 能很快
速的让我们找到出现异常的位置. 以后在实际工作中我们会采取更完备的方式来记录异常信息.

2.2 调用栈 定义

方法之间是存在相互调用关系的, 这种调用关系我们可以用 “调用栈” 来描述. 在 JVM 中有一块内存空间称为 “虚拟机栈” 专门存储方法之间的调用关系. 当代码中出现异常的时候, 我们就可以使用 e.printStackTrace(); 的方式查看出现异常代码的调用栈.

2.3 其他一些注意事项

  • catch 只能处理对应种类的异常 注意catch后面的异常类型不匹配情况
  • catch可以用多个

  • 代码执行到arr=null时候才会抛出空指针异常,所以before可以被打印,
    之后执行catch 空指针异常里面 代码块的代码;

结果如下:

一段代码可能会抛出多种不同的异常, 不同的异常有不同的处理方式. 因此可以搭配多个 catch 代码块.

  • 如果多个异常的处理方式是完全相同, 也可以写成这样
catch (ArrayIndexOutOfBoundsException | NullPointerException e) {...
}
  • 也可以用一个catch捕获所有异常(不推荐这样干)



由于 Exception 类是所有异常类的父类. 因此可以用这个类型表示捕捉所有异常.

备注: catch 进行类型匹配的时候, 不光会匹配相同类型的异常对象, 也会捕捉目标异常类型的子类对象.
如刚才的代码, NullPointerException 和 ArrayIndexOutOfBoundsException 都是 Exception 的子类, 因此都能被捕获到.

  • finally 表示最后的善后工作, 例如释放资源
    无论是否存在异常, finally 中的代码一定都会执行到. 列如:保证最终一定会执行到 Scanner 的 close 方法. 释放资源,提高效率

  • 使用 try 负责回收资源
    Scanner的close方法除了可以在finally代码块中执行释放,也存在一种等价写法, 将 Scanner 对象在 try 的 ( ) 中创建, 就能保证在 try 执行完毕后自动调用 Scanner的 close 方法.

try (Scanner sc = new Scanner(System.in)) { //执行完毕后自动调用 Scanner的 close 方法.int num = sc.nextInt();System.out.println("num = " + num);
} catch (Exception e) {e.printStackTrace();
}
  • 如果本方法中没有合适的处理异常的方式, 就会沿着调用栈向上传递

  • 如果向上一直传递都没有合适的方法处理异常, 最终就会交给 JVM 处理, 程序就会异常终止(和我们最开始未使用 try catch 时是一样的)

  • 关于finally关键字的注意事项:finally 执行的时机是在方法返回之前(try 或者 catch 中如果有 return 会在这个 return 之前执行 finally). 但是如果
    finally 中也存在 return 语句, 那么就会执行 finally 中的 return, 从而不会执行到 try 中原有的 return.

  • 一般不建议在 finally 中写 return (被编译器当做一个警告).

3.异常处理流程

  1. 程序先执行 try 中的代码
  2. 如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.
  3. 如果找到匹配的异常类型, 就会执行 catch 中的代码
  4. 如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.
  5. 无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).
  6. 如果上层调用者也没有处理的了异常, 就继续向上传递.
  7. 一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止.

4. 抛出异常

除了 Java 内置的类会抛出一些异常之外, 我们也可以手动抛出某个异常. 使用 throw 关键字完成这个操作.


在这个代码中, 我们可以根据实际情况来抛出需要的异常. 在构造异常对象同时可以指定一些描述性信息.

5.异常说明

我们在处理异常的时候, 通常希望知道这段代码中究竟会出现哪些可能的异常.
我们可以使用 throws 关键字, 把可能抛出的异常显式的标注在方法定义的位置. 从而提醒调用者要注意捕获这些异常.

6. Java 异常体系

Java 内置了丰富的异常体系, 用来表示不同情况下的异常.
下图表示 Java 内置的异常类之间的继承关系:

  • 顶层类 Throwable 派生出两个重要的子类, Error 和 Exception
  • 其中 Error 指的是 Java 运行时内部错误和资源耗尽错误. 应用程序不抛出此类异常. 这种内部错误一旦出现,除了告知用户并使程序终止之外, 再无能无力. 这种情况很少出现.
  • Exception 是我们所使用的异常类的父类.
  • 其中 Exception 有一个子类称为 RuntimeException , 这里面又派生出很多我们常见的异常类
    NullPointerException , IndexOutOfBoundsException 等.

Java语言规范将派生于 Error 类或 RuntimeException 类的所有异常称为 非受查异常(我理解为运行时异常), 所有的其他异常称为 受查异常.(编译时异常)

7.自定义异常类

Java 中虽然已经内置了丰富的异常类, 但是我们实际场景中可能还有一些情况需要我们对异常类进行扩展, 创建符合我们实际情况的异常.

例如, 实现一个用户登陆功能:

class NameException extends RuntimeException{public NameException(String message){super(message);}
}
class PasswordException extends RuntimeException{public PasswordException(String message){super(message);}
}
public class TestDemo2 {private static final String name="xxx";private static final String password="123";public static void login(String name,String password) throws NameException,PasswordException{if (!TestDemo2.name.equals(name)){throw new NameException("用户名错误!");}if (!TestDemo2.password.equals(password)){throw new PasswordException("密码错误!");}}public static void main(String[] args) {try {login("zzz","1234");}catch (NameException e){e.printStackTrace();System.out.println("请重新输入用户名!");}catch (PasswordException e){e.printStackTrace();System.out.println("密码错误!");}finally {System.out.println("执行finally");}}

此时在处理用户名或密码错误的时候可能就需要抛出两种异常. 我们可以基于已有的异常类进行扩展(继承), 创建和我们业务相关的异常类.

注意事项

  • 自定义异常通常会继承自 Exception 或者 RuntimeException
  • 继承自 Exception 的异常默认是受查异常(编译时异常)
  • 继承自 RuntimeException 的异常默认是非受查异常.(运行时异常)

    这个列子测试的是输入用户名错误时的情况,输入密码错误也同理,执行结果如下:

8. 结尾

有关Java异常知识的总结到这里就结束了~
如果觉得博主的文章对你有所帮助,欢迎大家多多点赞收藏~~

【Java】“异常”详解相关推荐

  1. Java异常详解及如何处理

    来源:Java异常详解及如何处理 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言 ...

  2. 【javaSE】java异常详解

    内容介绍 1 认识异常 1.1 初识异常 1.2 防御式编程 1.3 异常的好处 2 异常的用法 2.1 捕获异常 2.2 异常处理流程 2.3 抛出异常 2.4 异常说明 2.5 关于finally ...

  3. Java异常详解及自定义异常

    我已经不用 try catch 处理异常了!太烦人了_51CTO博客_try catch处理什么异常 一.异常的概念 1.定义(什么是异常?) 异常是例外,是一个程序在执行期间发生的事件,它中断正在执 ...

  4. 【Java基础知识 6】Java异常详解

    目录 一.Java异常简介 1.Exception和Error 2.NoClassDefFoundError 和 ClassNotFoundException 有什么区别?

  5. JAVA头部声明异常,Java 异常详解

    一.异常与错误的区别 再讲异常之前我们就应该要知道异常和错误的区别 Error类和Exception类的父类都是throwable类,他们的区别是: Error类一般是指与虚拟机相关的问题,如系统崩溃 ...

  6. Java泛型详解-史上讲解最详细的,没有之一

    目录 1. 概述 2. 一个栗子 3. 特性 4. 泛型的使用 4.1 泛型类 4.2 泛型接口 4.3 泛型通配符 4.4 泛型方法 4.4.1 泛型方法的基本用法 4.4.2 类中的泛型方法 4. ...

  7. Java虚拟机详解----JVM常见问题总结

    [正文] 声明:本文只是做一个总结,有关jvm的详细知识可以参考本人之前的系列文章,尤其是那篇:Java虚拟机详解04----GC算法和种类.那篇文章和本文是面试时的重点. 面试必问关键词:JVM垃圾 ...

  8. java 泛型详解、Java中的泛型方法、 java泛型详解

    本文参考java 泛型详解.Java中的泛型方法. java泛型详解 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即& ...

  9. 最详细的java泛型详解

    来源:最详细的java泛型详解 对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. ja ...

  10. flask与js交互的示例代码_Frida Java Hook 详解(安卓9):代码及示例(上)

    Frida Java Hook 详解(安卓9):代码及示例(上) 前言 1.1 FRIDA SCRIPT的"hello world" 1.1.1 "hello world ...

最新文章

  1. 智慧健康,协同发展:清华大学携手天津市共同探索健康医疗大数据
  2. Django部署(Apache)
  3. 主板是计算机所有部分连接的基础,计算机基础相关知识答案.doc
  4. LibSVM学习(二)——第一次体验libSvm
  5. [NOIP1999] 普及组
  6. Python之30秒就能学会的漂亮短程序代码
  7. android国家坐标,从坐标获取国家?
  8. 在发布ASP.NET网站的时候,出现state server错误
  9. Python学习之路day03——008用户输入input()方法
  10. 查看python包的版本
  11. linux 软连接和硬链接的区别
  12. 操作系统权限提升(十二)之绕过UAC提权-Windows UAC概述
  13. 【Xshell免费版,不用去找破解(ftp也一样)】
  14. linux git 三 版本查看、版本退回、
  15. 湖南省岳阳市谷歌高清卫星地图下载
  16. FZU 2198 快来快来数一数(矩阵快速幂)
  17. Vue源码学习之Computed与Watcher原理
  18. 静态变量什么时候会被回收
  19. 微信小程序之Array操作、图片上传
  20. pb 如何导出csv_用问卷网做问卷调查 如何导出数据报表?

热门文章

  1. Python Web实战:Python+Django+MySQL实现基于Web版的增删改查
  2. ACMNO.17C语言-筛法求素数 用筛法求之N内的素数。
  3. 万字详文告诉你如何做 Code Review
  4. 第一篇:时间和全局状态
  5. 在有序数字中寻找和为k的两个数 O(n)
  6. 安装MySQLdb for Python3.7
  7. 你应该知道的高性能无锁队列Disruptor
  8. 查找谁在使用文件系统
  9. 关于Mysql5.6半同步主从复制的开启方法【转】
  10. “黑客”一年能赚多少钱?