简单了解java中的异常

异常

1、异常的概述

1.1、概述

异常就是程序出现了不正常的情况,程序在执行过程中,数据导致程序不正常,最终导致JVM的非正常停止。语句错误不算在异常体系中。

1.2、异常的存在形式

异常有类型之分,比如我们比较熟悉的数组越界异常(ArrayIndexOutOfBoundsExceprion)空指针异常(NullPointerException)类型转换异常(ClassCastException)。当程序中产生异常时,其实就是在该异常的位置创建了一个该异常的对象,该对象携带了相关的异常信息因此,异常就是java中提供的类的对象

1.3、程序中出现异常,怎么处理

程序中一旦产生了异常,首先会首先会中断向下执行。异常的传递要根据处理方式而定,如果没有处理,默认是将异常传递给本方法调用者。不断往回传递,知道JVM收到异常信息,此时程序终止执行。

2、异常的体系

  • Error:严重问题,通过代码无法处理。
  • Exception:称之为异常类,它表示程序本身可以处理的问题
    • RuntimeException及其子类:运行时异常。(空指针异常、数组越界异常)
    • 非RuntimeException及其子类:编译时异常,编译时必须处理的,否则程序不能通过编译。(日期格式化异常)
      异常体系

3、虚拟机异常处理方式

JVM的默认处理方案:

如果程序中出现了问题,我们没有没有做任何处理,最终JVM会做默认处理,那么JVM是如何处理的嘞?

  • 把异常的类型、原因、位置打印在控制台
  • 程序停止运行

注意:程序中出现了异常,会在当前位置创建此异常的对象,对象中包含了异常的信息,并把此异常交给本方法的调用者处理。

4、手动处理异常-声明和抛出

4.1、声明异常——throws

格式:

修饰符 返回值类型 方法名(参数列表) throws 异常类型1, 异常类型2...{...}

示例:

public void show() throws NullPointerException, ArrayIndexOutOfBoundsException {...}

作用:

  • 表示告知调用者当前的方法可能会出现某些异常,使用时需要注意
  • 如果当前方法没有出现任何异常,那么代码会正常执行
  • 如果当前方法中出现了异常,会把异常交给本方法调用者处理

代码演示:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo1 {
    public static void main(String[] args) throws ParseException {
        //自己处理
        demo1("糖锅");

        //demo2()方法中声明的异常,需要在main方法中处理掉,main方法继续向上抛出ParseException异常
        demo2();
    }

    //运行时异常:RuntimeException(父类)
    //子类:NullPointerException
    public static void demo1(String name) throws NullPointerException {
        System.out.println(name.length());
    }

    //编译时异常:Exception(父类)
    //子类:ParseException
    public static void demo2() throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        //编译时异常,必须有异常处理代码(声明、捕获)
        Date date = simpleDateFormat.parse("2024-6-9");
    }
}

总结:

  • 编译时异常因为在编译时就会检查,所以必须要写在方法后面进行显式声明

  • 运行时异常因为在运行时才会发生,所以在方法后面可以不写

  • 如果声明多个异常有子父类关系,那么只需要声明一个父类即可(多态)

    什么意思嘞?

    就比如我们此时又创建了一个demo3方法,其参数是一个数组和一个字符串,在运行时可能发生数组越界,和空指针异常,此时我们声明异常IndexOutOfBoundsException和NullPointerException

    public static void demo3(int[] array, String str) throws IndexOutOfBoundsException, NullPointerException{
            System.out.println(array[999]);
        }
    

    这样写没有问题,但是这样看起来代码看起来很冗余,所以我们可以直接声明它们的父类RuntimeException即可

    public static void demo3(int[] array, String str) throws RuntimeException{
            System.out.println(array[999]);
        }
    

4.2、throw——抛出异常

格式:

修饰符 返回值类型 方法名(参数列表){
	throw new 异常类型();
}

注意:

  • 抛出异常的格式必须在方法内部完成
  • 如果手动抛出一个异常,下面的代码无法执行

示例:

抛出异常下代码不执行

抛出异常的意义所在:

  • 在方法中,但传递的参数有误时,没有继续运行下去的意义了,则采取抛出处理,表示让该方法结束运行。
  • 告诉调用者方法中出现的问题

throws和throw的区别:

throwsthrow
用在方法声明后,跟的是异常类名用在方法体内,跟的是异常对象
表示声明异常,调用该方法有可能出现这样的异常表示手动抛出异常对象,告知调用者数据传输有误
异常对象又JVM创建异常对象我们自己创建

4.3、捕获

4.3.1、捕获处理异常介绍:try,catch

之前的声明或者抛出都是将异常传递出去,让调用者知道异常信息。而捕获处理是本方法内部进行处理,能够阻止异常的传递,从而保证程序能够继续往下执行。

4.3.2、捕获异常的格式
try{
    //try中存放可能出现问题的代码
    //1、代码1...
    //2、代码2...
    //3、代码3...
}catch(){
    //4.处理异常方案
    //举例:打印异常,获取异常原因记录日志
}
//5、其他代码
4.3.3、捕获异常执行方式

如果try中没有遇到问题,怎么 执行?

从上往下一次执行,catch不执行

如果try中代码2遇到了问题,问题下面的代码还会执行吗?

不会执行了,会拿当前异常对象和异常类型匹配,匹配成功执行执行处理异常代码

如果出现的问题没有捕获,那么程序如何运行?

如果异常没有捕获到,虚拟机会帮助我们处理异常

同时有可能出现多个异常如何处理?

  • 多次捕获,多次处理
try{
    //异常1
}catch(异常1){}

try{
    //异常2
}catch(异常2){}
...
  • 一次捕获,多次处理
try{
    //异常1
    //异常2
    ...
}catch(异常1){
    //处理异常1
}catch(异常2){
    //处理异常2
}...
  • 一次捕获,一次处理
try{
    //异常1
    //异常2
    ....
}catch(Exception e){
    
}

示例:

定义一个demo方法可以将字符串时间转换为时间类型,简单捕获并处理可能出现的异常

import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExceptionDemo3 {
    private static final Logger LOGGER = LoggerFactory.getLogger("ExceptionDemo3");

    public static void main(String[] args) {
        String bir = "2024-6-23";

        try {//监视可能发生异常的代码

            //调用的方法可能发生异常,自己处理
            Date resBir = demo(bir);

            System.out.println(resBir);
        } catch (ParseException e) {//拿异常对象类型和当前定义的异常类型进行匹配
            System.out.println("开始处理异常~");

            //在日志中记录日常
            LOGGER.error(e.getMessage());
        }

        System.out.println("程序继续执行");
    }

    public static Date demo(String demoBir) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");

        return simpleDateFormat.parse(demoBir);
    }
}

以上只是一个简单的处理方式,还有其它处理方式,大家可以自行尝试。

小结:

异常处理方式有两种:声明、捕获,那么在程序开发中我们该如何选择呢?

  • 自定义方法(程序员自己定义的方法):通常都可以使用声明,因为这样做方法体内的代码会比较清爽(阅读性好),把异常统一抛出到main方法中,进行统一处理。

  • 捕获的使用场景:main方法中只能使用捕获,父亲型中的方法不支持throws,在子类重写方法时,重写的方法只能使用捕获。

5、Throwable类中常用的方法

Throwable的成员方法

方法名说明
public String getMessage ()返回此Throwable的详细消息字符串
public String toString ()返回此可抛出的简短描述
public void printStackTrace ()把异常的控制信息输出在控制台

以4.3.3中的示例来演示说明(在catch中添加如下代码)

  • getMessage
System.out.println(e.getMessage());

结果展示

Unparseable date: "2024-6-23"
  • toString
System.out.println(e.toString());

结果展示

java.text.ParseException: Unparseable 
  • printStackTrace
e.printStackTrace();

结果展示(方便程序员定位异常位置)

java.text.ParseException: Unparseable date: "2024-6-23"
	at java.text.DateFormat.parse(DateFormat.java:366)
	at com.tg.log.ExceptionDemo3.demo(ExceptionDemo3.java:38)
	at com.tg.log.ExceptionDemo3.main(ExceptionDemo3.java:20)

6、自定义异常

6.1、概述

当jdk中的异常类型,不满足实际的业务需要时。就可以自定义异常。比如,一个人的的年龄数据,如果是负数认为是不合法的,这就需要抛出异常,jdk中就没有表示年龄的异常,就需要我们自己定义异常了。

6.2、实现

public 自定义异常类 extends Exception{//当前自定义异常为:编译时异常
    public 自定义异常类(){
        super();//调用父类中的无参构造方法,可以省略不写
    }
    
    public 自定义异常类(String message){
        super(message);//不能省略
    }
}



public 自定义异常类 extends RunTimeException{//当前自定义异常为:运行时异常
    public 自定义异常类(){
        super();//调用父类中的无参构造方法,可以省略不写
    }
    
    public 自定义异常类(String message){
        super(message);//不能省略
    }
}

示例:定义一个打印年龄的方法,年龄不能是负数

定义AgeOutOfBoundsException异常类

public class AgeOutOfBoundsException extends RuntimeException{
    public AgeOutOfBoundsException() {

    }

    public AgeOutOfBoundsException(String message) {
        super(message);
    }
}

演示异常处理

public class ExceptionDemo4 {
    public static void main(String[] args) {
        int age = -1;

        try {
            printAge(age);
        }catch (AgeOutOfBoundsException e){
            System.out.println("处理年龄不合法异常");
        }
    }

    public static void printAge(int age){
        if(age < 0){
            throw new AgeOutOfBoundsException("年龄不能是负值!");
        }

        System.out.println("年龄:" + age);
    }
}

运送结果

处理年龄不合法异常

oid main(String[] args) {
int age = -1;

    try {
        printAge(age);
    }catch (AgeOutOfBoundsException e){
        System.out.println("处理年龄不合法异常");
    }
}

public static void printAge(int age){
    if(age < 0){
        throw new AgeOutOfBoundsException("年龄不能是负值!");
    }

    System.out.println("年龄:" + age);
}

}


运送结果

~~~java
处理年龄不合法异常

ok,说完啦,收工!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/696398.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

安装golang

官网:All releases - The Go Programming Language (google.cn) 下载对应的版本安装即可

数据结构初阶 · 链式二叉树的部分问题

目录 前言&#xff1a; 1 链式二叉树的创建 2 前序 中序 后序遍历 3 树的节点个数 4 树的高度 5 树的叶子节点个数 6 树的第K层节点个数 前言&#xff1a; 链式二叉树我们在C语言阶段已经实现了&#xff0c;这里介绍的是涉及到的部分问题&#xff0c;比如求树的高度&am…

liquibase做数据库版本管理

通过这个配置就会自动启动liquibase 比对 https://www.cnblogs.com/ludangxin/p/16676701.html https://zhuyizhuo.github.io/2020/07/04/spring-boot/spring-boot-liquibase-database-version-control/

如何理解与学习数学分析——第二部分——数学分析中的基本概念——第10章——实数

第2 部分&#xff1a;数学分析中的基本概念 (Concepts in Analysis) 10. 实数(The Real Numbers) 本章介绍比率数(rational numbers)和非比数(irrational numbers)及其与十进制展开的关系。讨论了实数的公理&#xff0c;并解释了完备性公理对于区分实数和比率数为何必不可少&…

IDEA启动项目报java.lang.OutOfMemoryError: GC overhead limit exceeded

idea编译项目时报j ava.lang.OutOfMemoryError: GC overhead limit exceeded错误&#xff0c;教你两步搞定&#xff01; 第一步&#xff1a;打开help -> Edit Custom VM Options ,修改xms和xmx的大小&#xff0c;如下图&#xff1a; 第二步&#xff1a;File -> Settings…

基于JSP的足球赛会管理系统

你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;IDEA/Eclipse、Navicat、Maven 系统展示 首页 个人中心 球队介绍…

使用 Sysbench 测试文件的读写速度

要使用 Sysbench 测试文件的读写速度&#xff0c;你可以按照以下步骤进行&#xff1a; 安装 Sysbench&#xff1a; 如果你还没有安装 Sysbench&#xff0c;可以通过以下命令在 Ubuntu 上安装&#xff1a; sudo apt install sysbench创建测试文件&#xff1a; 首先&#xff0c…

Xilinx(AMD) vivado对FPGA网表文件进行功能仿真的方法

1 概述 在FPGA开发中很多商用IP核出于知识产权保护的目的&#xff0c;不提供源代码&#xff0c;而是提供综合后的FPGA网表。由于没有源代码&#xff0c;也无法对网表文件直接进行仿真的操作来验证功能&#xff0c;此时需要独立的仿真模型文件。 本文介绍在Xilinx(AMD) vivado软…

LVGL移植和图片显示

最近闲来无事&#xff0c;偶尔刷到了移植LVGL的教程&#xff0c;今天肝完了机械原理又移植完LVGL库&#xff0c;真是收获满满的一天&#xff0c;先接一杯水去。 回来了&#xff0c;发个朋友圈高级一下&#xff0c;好困。 lvgl v8.3移植及组件使用_lvgl界面编辑器-CSDN博客htt…

MySQL限制登陆失败次数配置

目录 一、限制登陆策略 1、Windows 2、Linux 一、限制登陆策略 1、Windows 1&#xff09;安装插件 登录MySQL数据库 mysql -u root -p 执行命令安装插件 #限制登陆失败次数插件 install plugin CONNECTION_CONTROL soname connection_control.dll;install plugin CO…

英伟达:史上最牛一笔天使投资

200万美元的天使投资&#xff0c;让刚成立就面临倒闭风险的英伟达由危转安&#xff0c;并由此缔造了一个2.8万亿美元的市值神话。 这是全球风投史上浓墨重彩的一笔。 前不久&#xff0c;黄仁勋在母校斯坦福大学的演讲中&#xff0c;提到了人生中的第一笔融资——1993年&#x…

离散数学答疑 5

知识点&#xff1a;单侧连通&#xff0c;强连通&#xff0c;弱连通 前缀码&#xff1a;比如001和00101就不是。因为后者的前三位和前者的重复了 有向图的邻接矩阵求法&#xff1a;横着看 数据结构21-4分钟搞定邻接矩阵_哔哩哔哩_bilibili 可达矩阵是包含自反性的。可达矩阵是…

Objective-C的初始化方法中,应该如何读写属性

除非有明确的原因需要使用setter, getter, 否则总是应该直接访问, 也就是直接使用实例变量&#xff08;也称为 iVar&#xff09;来读写数据 理由&#xff1a; 避免子类覆盖setter方法的影响&#xff1a;若在初始化方法中使用setter方法, 使用此方法实例化子类, 可能会调用子类…

DeepSpeed Learning Rate Scheduler

Learning Rate Range Test (LRRT) 训练试跑&#xff0c;该lr scheduler从小到大增长lr&#xff0c;同时记录下validatin loss&#xff1b;人来观察在训练多少step之后&#xff0c;loss崩掉&#xff08;diverge)了&#xff0c;进而为真正跑训练&#xff0c;挑选合适的lr区间&…

帕友的小贴士,锻炼

帕金森病作为一种慢性神经系统疾病&#xff0c;对患者的生活质量产生了深远的影响。虽然医学界对于帕金森病的治疗仍在不断探索&#xff0c;但合理的锻炼已经被证实是改善患者症状、提高生活质量的有效途径之一。本文旨在为帕金森病患者推荐一些适合的锻炼方法&#xff0c;帮助…

57.Semaphore信号量

用来限制能同时访问共享资源的线程上限。只是适合限制单机线程数量。 Slf4j public class SemaphoreDemo {public static void main(String[] args) {Semaphore semaphore new Semaphore(3);for (int i 0; i < 10; i) {new Thread(() -> {try {semaphore.acquire();//…

【C++类和对象中篇】(构造函数和析构函数)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f369;1.默认成员函数的概念&#xff1a; &#x1f369;2.构造函数&#xff1a; 2.1特性&…

深度学习模型的生命周期与推理系统架构

目录 深度学习模型的生命周期 ​编辑 深度学习模型的生命周期 推理相比训练的新特点与挑战 推理系统架构 推理系统 vs 推理引擎 顶层:API接口和模型转换 中层:运行时(计算引擎) 底层:硬件级优化 边缘设备计算 主要问题 边缘部署和推理方式 方式1:边缘设备计…

问题汇总:MPU6050(软件iic)

以下为个人问题汇总&#xff0c;排查点汇总可能大有缺陷&#xff0c;如有错误&#xff0c;欢迎指正。 排查点汇总 检查软件iic的时序操作用示波器或逻辑分析仪检查波形 无法使用逻辑分析仪进行I/O引脚波形分析 充当SDA、SCL的引脚要配置为推挽输出; 另外&#xff0c;逻辑分…

纳什均衡:博弈论中的运作方式、示例以及囚徒困境

文章目录 一、说明二、什么是纳什均衡&#xff1f;2.1 基本概念2.2 关键要点 三、理解纳什均衡四、纳什均衡与主导策略五、纳什均衡的例子六、囚徒困境七、如何原理和应用7.1 博弈论中的纳什均衡是什么&#xff1f;7.2 如何找到纳什均衡&#xff1f;7.3 为什么纳什均衡很重要&a…