希望通过博客和大家相互交流,相互学习,如有错误,请评论区指正

文章目录

  • 一、什么是异常?
    • Java的异常体系
    • 如何排查异常
  • 二、 处理异常
    • try…catch基本语法
    • 这个时候就要处理异常
    • 如果我们用Exception来捕获异常呢?
    • finally
    • 在方法中出现异常
    • 异常处理流程
    • 手动抛出异常
  • 三、自定义异常
    • 源码剖析
    • 自定义
    • 注意

如下实例:

public class Demo {public static void main(String[] args) {int num = 2/0;}
}

这段代码中“除0”的逻辑在C语言中就只是报个警告,但是Java是比较安全的语言,在编译运行的时候会直接抛出异常

那么到底什么是异常?

一、什么是异常?

异常指的是在程序运行过程中发生的异常事件,通常是由外部问题(如硬件错误、输入错误)所导致的。在Java等面向对象的编程语言中异常属于对象.

异常本身是一个对象,产生异常就是产生了一个异常对象

Java的异常体系


我们都知道Java中所有类都是继承自Object的,Throwable这个类也是如此,如下Java官方文档

我们可以看到

继承于throwable类的有两个,一个是Error(错误),一个是Exception(异常),throwable是Java中所有错误和异常的父类

而异常又分为受查异常非受查异常(我们之前碰到过的除0发生的异常就是非受查异常)

非受查异常:Java语言规范将派生于 Error 类或 RuntimeException 类的所有异常称为非受查异常(因为程序的代码Bug导致的问题,空指针异常,数组下标越界异常)

受查异常:所有的其他异常称为 受查异常(程序编译时抛出的异常),必须处理,否则代码编译不能通过(一些可以经过重试或者程序自动修复可以解决的问题)

错误:因为设备或其他硬性环境导致的,程序根本无法修复的问题

如何排查异常

如下代码:

在文章开头写的一个"除0"代码的运行结果:

这里面java.lang.ArithmeticException是异常的种类,by zero是异常的具体信息

常见的异常种类有:

NullPointerException:空指针异常

ArithmeticException:算术异常

ArrayIndexOutOfBoundsException:数组下标越界异常

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

有的时候异常信息会有很多行,这些异常信息被称为异常信息栈/异常跟踪栈,那么我们如何在这些异常信息中找到引发异常的第一现场呢?

直接点击最上面第一条异常信息的蓝色部分,光标就会自动跳转到引发异常的地方,从而进行相应的修改

二、 处理异常

Java当中异常的核心思想其实就是让我们先操作,在操作过程中遇到问题再处理

try…catch基本语法

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

我们还是以"除0"问题为例

public static void main(String[] args) {int a = 10/0;System.out.println("666");
}

这个程序显然到了int a = 10/0;就会抛出异常,后面的666不会被打印出来

此处发生异常,程序会直接交给JVM处理异常,导致的结果是程序会立即停止,不再向下执行

那么我们如果想要让程序继续往下执行呢?

这个时候就要处理异常

public static void main(String[] args) {try {int a = 10 / 0;} catch (ArithmeticException e) {e.printStackTrace();}System.out.println("666");
}

在try中放入可能会引发异常的语句,在catch后面的圆括号内写入想要捕获异常的种类ArithmeticException,然后就可以对此异常做出处理,e.printStackTrace();打印异常追踪栈,最后再打印666

运行结果:

当程序抛出异常的时候,由catch块进行捕获,程序自己来处理异常,导致的结果就是程序会继续向下执行

注意:如果catch中要捕获的异常种类和实际发生异常的种类不一样的话,就还是交给JVM处理了,程序立即停止

如果我们用Exception来捕获异常呢?

如下代码

public static void main(String[] args) {try {int a = 10 / 0;}catch (Exception e) {System.out.println(999);}catch (ArithmeticException e) {System.out.println(888);}     // 直接捕获Exception的话,后面的这些catch就没啥用了,编译器就会报错System.out.println("666");
}

所有异常继承于Exception,那么当出现异常的时候,Exception可以捕获所有的异常,这样只需要写一个捕获Exception的catch就行了,但是不建议这么写,这样得不到具体的异常种类

finally

无论catch有没有捕获到异常,finally块中的代码都会在最后被执行

public static void main(String[] args) {try {int a = 10 / 0;System.out.println("666");}catch (ArithmeticException e) {System.out.println("888");}finally {System.out.println("999");}System.out.println("777");
}

在方法中出现异常

如果本方法中没有合适的处理异常的方式,就会沿着调用栈向上传递

public class ExceptionLearning {public static void demo() {int a = 10/0;}public static void main(String[] args) {demo();}
}

运行结果:

在demo方法中执行时,抛出算术异常,因为demo方法是被main方法调用的,所以demo就会让main方法来处理异常,但是main方法中也没有处理异常,就会交给JVM来处理,程序就会异常终止

若对异常做出处理

public class ExceptionLearning {public static void demo() {int a = 10/0;}public static void main(String[] args) {try {demo();}catch (ArithmeticException e) {e.printStackTrace();}finally {System.out.println("继续向下执行");}}
}

在demo方法中执行时,抛出算术异常,因为demo方法是被main方法调用的,所以demo就会让main方法来处理异常,main方法中对异常做出处理,程序继续向下执行

异常处理流程

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

手动抛出异常

除了Java编译器来抛出异常以外,我们也可以自己针对一些情况来抛出异常

三、自定义异常

要知道,异常本身就是一个对象,它肯定是对应一个类的,那么我们也可以通过创建类的方式来自定义异常

源码剖析

我们这里以Arithmetic类为例,可以先看看它的源码

从源码中会发现Arithmetic这个类继承自RuntimeException类,并且有两个构造方法,一个有参,一个无参

自定义

我们也可以仿照Arithmetic来自定义,如下代码

class MyException extends RuntimeException{public MyException() {super();}public MyException(String str) {super(str);}
}
public class ExceptionLearning {public static void main(String[] args) throws MyException{   //在方法上加上异常说明, 相当于将处理动作交给上级调用者int b = 0;if (b == 0) {throw new MyException("b == 0");}}
}

运行结果

注意

当我们将MyException继承于RuntimeException的时候,这个异常就默认是非受查异常;继承于Exception的时候,这个异常就默认是受查异常

Java针对受查异常,强制要求: 一个方法如果抛出了受查异常,则必须通过throws声明异常

【JavaSE】异常 超详讲解(编程思想)相关推荐

  1. 超详讲解图像拼接/全景图原理和应用 | 附源码

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 概述 图像拼接是计算机视觉中最成功的应用之一.如今,很难找到不包含 ...

  2. AtCoder Beginner Contest 244 B题(超详讲解)

    目录 题目 状态 代码及讲解 结语 题目 Time Limit: 2 sec / Memory Limit: 1024 MB Score : 200 points Problem Statement ...

  3. python全景图像拼接_超详讲解图像拼接/全景图原理和应用 | 附源码

    研究好玩又有用的技术第 008 期 在学习中发现快乐,在应用找到价值.这是我第八期分享图像技术应用的文章. 前七期欢迎阅读和分享: 概述 作者:Thalles Silva 编译:AI算法与图像处理 图 ...

  4. 二叉树——根据 中序 和 层序 建树,超详讲解。

    模板题传送 背景: 树和二叉树基本上都有先序.中序.后序.按层遍历等遍历顺序,给定中序和其它一种遍历的序列就可以确定一棵二叉树的结构. 假定一棵二叉树一个结点用一个字符描述,现在给出中序和按层遍历的字 ...

  5. 【ES6】ES6超详讲解(@_@;)

    文章目录 一.初识ES6 let和const 二.模板字符串与箭头函数 模板字符串 箭头函数 this指向 不适合箭头函数的场景 三.解构赋值 什么是解构赋值 数组的解构赋值 数组解构赋值的默认值 类 ...

  6. 你该懂的,IP地址超详讲解

    一.简介 IP地址分为IPV4 IPV6,我们这里所说的IP地址指的是IPV4的地址. IPV4( InternetProtocol Version 4 )互联协议版本4,有版本V4之前就有IPV1I ...

  7. python高级语法装饰器_Python高级编程——装饰器Decorator超详细讲解上

    Python高级编程--装饰器Decorator超详细讲解(上篇) 送你小心心记得关注我哦!! 进入正文 全文摘要 装饰器decorator,是python语言的重要特性,我们平时都会遇到,无论是面向 ...

  8. 【平衡小车制作】(一)硬件原理图讲解(超详解)

      大家好,我是小政.之后的一系列文章我将介绍我玩平衡小车的过程以及遇到的一些问题,将这些内容记录下来分享给大家,也让大家少走一些弯路.接下来我将从硬件框架选择.软件编程.PID算法.PID调参.蓝牙 ...

  9. 超全、超详的Spring Boot配置讲解笔记

    超全.超详的Spring Boot配置讲解笔记 springboot默认加载配置 SpringBoot使用两种全局的配置文件,全局配置文件可以对一些默认配置进行修改. application.prop ...

最新文章

  1. 宿主机( win 7 系统) ping 虚拟机VMware( cent os 6.6 ) 出现“请求超时”或者“无法访问目标主机”的解决方法
  2. DBHelper 使用的是存储过程
  3. service层自定义异常事物回滚
  4. BZOJ.4552.[HEOI2016/TJOI2016]排序(线段树合并/二分 线段树)
  5. SDNU 1406.A+B问题(水题)
  6. android 生成推广图片保存_flutter 如何生成图片并保存到手机相册?
  7. 计算机基础及msoffice应用好考吗,全国计算机等级考试考试一级WPS Office和MS Office有什么不同?那个好考?...
  8. 如何了解自己的认知偏差_了解吸引力偏差
  9. 机器学习相关从业者如何兼顾理论与工程能力
  10. 谈谈我这几年的C++学习之路
  11. byte初始化并赋值_一位数组的定义、赋值和初始化.note
  12. Python自动化之高级语法单例模式
  13. [导入]在SYBASE数据库中使用游标(Cursors)将多行查询结果进行逐行处理
  14. 百度深度学习初级工程师认证划水贴
  15. 宏、函数、宏和函数的区别
  16. 小米网络信号测试软件,iQOO和小米9网络测试 iQOO和小米9谁的信号会更好一些
  17. 【OI好题推荐 #1】洛谷-P1183 多边形的面积
  18. Tomcat的appBase,docBase,path关系
  19. 机器人 瓷砖墙面清洗_墙壁清洁机器人
  20. CF Make Cents?

热门文章

  1. 赛尔号星球大战服务器维修,《赛尔号星球大战》12月21日停服更新公告
  2. Libnids--函数调用顺序之nids_init()
  3. python程序发布到阿里云云服务器_Python实现阿里云服务器里的文件上传与下载
  4. 四川大学计算机研究生学习氛围,川大清退上百名研究生
  5. Lindows来了,Windows咋办?
  6. SpringCloud-30-Spring Cloud Config+Bus 实现配置的动态刷新
  7. python opencv读取图像像素值_python-opencv--图像像素通道读取及修改
  8. 题:上课睡觉(暴力枚举)
  9. edup无线网卡linux,linux 下安装hostapd 让网卡做热点
  10. embarrass的用法和搭配_embarrass的短语