异常(Java)

news2024/9/27 17:25:49

目录

1. 异常的概念

2. 异常的分类

3. 异常的处理

4. 异常的抛出

5. 异常的捕获

5.1 异常声明throws

5.2 try-catch捕获并处理

5.3 finally

6. 异常的处理流程

7. 自定义异常类


1. 异常的概念

异常就是在程序执行过程中发生的不正常的行为.异常中断了正在执行程序的正常指令流。

异常其实就是类.异常是可以继承的。

算数异常、空指针异常、下标越界异常

  1. throwable:是异常体系的顶层类,派生出两个子类:Error和Exception
  2. Error:Jav虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等
  3. Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行

2. 异常的分类

异常包括:运行时异常(不受查异常)和编译时异常(受查异常)

注意:

编译时出现的语法性错误,不能称为异常,这是“编译期”出错,而运行时指的是程序已经编译通过得到class文件了,再由JVM执行过程中出现的错误。

3. 异常的处理

1.LBYL:Look Before You Leap.在操作之前就做充分地检查。即:事前防御型

缺陷:正常流程和错误处理流程代码混在一起,代码整体显得较为混乱

2.EAFP:It's Easier to Ask Forgiveness than Permission.“事后获取原谅比事前获取许可更容易”。先操作,遇到问题再处理,即:事后认错型

优势:正常流程和错误流程是分离开的,代码更清晰,更易理解。

异常处理的核心思想就是EAFP

在java中,异常处理的5个关键字:throw,try,catch,finally,throws

4. 异常的抛出

在编写程序时,如果程序出现错误,需要将错误的信息告知调用者,比如:参数检测

在java中,可以借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者,具体语法如下:

throw new XXXException("异常产生的原因");
public class Test {
    public static void testException(int a) {
        if (a == 0) {
            throw new ArithmeticException("a==0");
        }
    }

    public static void main(String[] args) {
        testException(0);
    }
}

注意:

  1. throw必须写在方法体内部
  2. 抛出的对象必须是Exception或者Exception的子类对象
  3. 如果抛出的是RunTimeException或者RunTimeException的子类,则可以不用处理,直接交给JVM来处理
  4. 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
  5. 异常一旦抛出,其后的代码就不会执行

5. 异常的捕获

异常的捕获,也就是异常的具体处理方式,主要有两种:异常声明throws以及try-catch捕获处理。

5.1 异常声明throws

处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想处理该异常,就可以借助throws将异常交给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常。

    public static void testException(int a) throws NullPointerException {
        if (a == 0) {
            throw new ArithmeticException("a==0");
        }
    }

注意:

  1. throws必须跟在方法的参数列表之后
  2. 声明的异常必须是Exception或者Exception的子类
  3. 方法内部如果抛出多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型具有父子关系,直接声明父类即可
  4. 调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出
5.2 try-catch捕获并处理

throws对异常没有真正处理,而是将异常报告给抛出异常方法的调用者,由调用者处理。如果真正要对异常进行处理,就需要try-catch.

public class Test {
    public static void function(int a) throws CloneNotSupportedException {
        if (a == 10) {
            throw new CloneNotSupportedException();
        }
    }

    public static void main(String[] args) {
        try {
            function(10);
            System.out.println("haha");
        } catch (CloneNotSupportedException e) {
            System.out.println("捕获异常,处理异常");//
        }
        System.out.println("程序继续执行");//
    }
}
public class Test {
    public static void main(String[] args) {
        int[] array = {1, 2, 3};
        try {
            //System.out.println(array[4]);
            array=null;
            System.out.println(array.length);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("处理ArrayIndexOutOfBoundsException异常");//
            e.printStackTrace();
            //java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 3
            //	at Test.main(Test.java:5)
        } catch (NullPointerException e) {
            System.out.println("处理NullPointerException异常");
            e.printStackTrace();
            //java.lang.NullPointerException: Cannot read the array length because "array" is null
            //	at Test.main(Test.java:7)
        }
        System.out.println("after");//
    }
}

不会同时抛出多个异常类型

不能任何异常都用Exception解决,Exception是所有异常的父类,从上到下进行捕捉

  1. try块内抛出异常位置之后的代码将不会被执行
  2. 如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理,继续往外抛,直到JVM收到后中断程序--异常是按照类型来捕获的
  3. try中可能会抛出多个不同的异常对象,则必须用多个catch来捕获--即多种异常,多次捕获
  4. 如果异常之间具有父子关系,一定是子类异常在前catch,父类异常在后catch,否则语法错误
  5. 可以通过一个catch捕获所有的异常,即多个异常,一次捕获(不推荐)

由于Exception类是所有异常类的父类,因此可以用这个类型捕获所有异常

5.3 finally

不管是否发生异常,finally都会被执行,一般用于资源的释放。另外,因为异常会引发程序的跳转,可能导致有些语句执行不到,finally就是用来解决这个问题。

finally执行的时机是在方法返回之前(try或者catch中如果有return会在这个return之前执行finally)。但是如果finally中也存在return语句,就会执行finally中的return,从而不会执行到try中原有的return.

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

throw和throws的区别:

throw和throws的区别-CSDN博客

6. 异常的处理流程

public class Test {
    public static void test1() {
        int[] array = {1, 2, 3, 4};
        System.out.println(array[10]);
    }

    public static void main(String[] args) {
        try {
            test1();
        } catch (ArrayIndexOutOfBoundsException e) {

        }
        System.out.println("异常已处理");//
    }
}

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

异常处理流程总结:

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

7. 自定义异常类

Test类:

package demo;

class login {
    private String name;
    private String password;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void logIn(String name, String password) throws PassWordException, NameException {
        if (!this.name.equals(name)) {
            throw new NameException("用户名错误异常");
        } else if (!this.password.equals(password)) {
            throw new PassWordException("密码错误异常");
        } else {
            System.out.println("登录成功!");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        login login = new login();
        login.setName("admin");
        login.setPassword("123456");
        try {
            login.logIn("admin", "12456");
        } catch (PassWordException e) {
            e.printStackTrace();
        } catch (NameException e) {
            e.printStackTrace();
        } finally {

        }
    }
}

PassWordException类:(自定义)

package demo;

public class PassWordException extends RuntimeException {//运行时异常

    public PassWordException() {
        super();
    }

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

NameException类:(自定义)

package demo;

public class NameException extends RuntimeException {
    public NameException() {
        super();
    }

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cross-Modality Person Re-identification with Memory-Based Contrastive Embedding

文章目录 题目:Cross-Modality Person Re-identification with Memory-Based Contrastive Embedding(基于记忆对比嵌入的跨模态人物再识别)摘要论文分析网络框架1、Problem Definition(模态预处理)2、Learning Modalit…

RUM技术探索:前端监控数据采集与实践

​​随着互联网技术的不断演进,Web应用程序正日益呈现出复杂多变与高度动态性的特征。用户渴望获得快速的页面加载、流畅的交互体验以及高度的可靠性。为了满足这些,实时监控 Web 应用的性能和行为变得至关重要。前端监控让开发者能够深入了解应用的表现…

Hack The Box-Resource

总体思路 phar反序列化->SSH CA私钥泄露->SSH CA私钥滥用->SSH脚本滥用 信息收集&端口利用 nmap -sSVC itrc.ssg.htb目标开放了两个ssh端口和一个80端口,先查看80端口 网站是一个SSG IT资源中心,主要用于解决网站问题、管理 SSH 访问、清…

免费【2024】springboot 付费自习室管理系统的设计与实现

博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

正点原子imx6ull-mini-Linux驱动之Linux 音频驱动实验

虽然mini板子没有这个资源,但是可以学学移植这个软件。 音频是我们最常用到的功能,音频也是 linux 和安卓的重点应用场合。I.MX6ULL 带有 SAI 接口,正点原子的 I.MX6ULL ALPHA 开发板通过此接口外接了一个 WM8960 音频 DAC 芯片,…

《程序猿入职必会(10) · SpringBoot3 整合 MyBatis-Plus》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…

使用samba在ubuntu和windows之间共享文件

1、在ubuntu上安装samba 在终端输入命令 sudo apt update sudo apt install samba 2、配置samba 打开samba 的配置文件 sudo nano /etc/samba/smb.conf 在文件末尾添加以下内容 [shared] path /home/lzx available yes valid users lzx read only no browsable yes…

【Redis进阶】Redis的持久化RDB和AOF

目录 持久化 RDB持久化 概念 原理 RDB 持久化的详细工作流程 1触发持久化: 2创建子进程: 3数据写入 RDB 文件: 4替换旧文件: 5回收子进程: RDB持久化的触发方式 1.手动触发: 2.自动触发&#…

鸿蒙应用服务开发【获取天气数据】

获取天气数据 介绍 Weather Service Kit(天气服务)是鸿蒙生态下的一个数据提供服务, Weather Service Kit融合了多家气象行业TOPs供应商,提供专业、精准、稳定的超本地化天气数据服务, 开发者可以通过Weather Servic…

Tomcat 漏洞

1.CVE-2017-12615 抓包,将get改为put jsp文件后加/ 访问木马使用蚁剑连接 2.弱口令 点击后输入默认用户名、密码:tomcat/tomcat 登录成功,在文件上传位置上传war包 使用哥斯拉生成一个jsp木马,打包,改后缀为war,上传…

如何有效防御短信接口遭受恶意攻击?

短信接口若遭遇恶意攻击,不仅加剧企业运营成本,更将严重损害企业形象。为有效预防此类风险,以下策略值得采纳: 1.设定合理的发送间隔:针对同一手机号码,设定合理的重复发送短信时间间隔,建议范…

Unity动态修改按钮点击效果

动态修改按钮色块,达到保留选中效果。 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class Demo: MonoBehaviour {private Button _frontBtn;private Button _backBtn;public ColorBlock NormalC…

【React】深入解析ref的使用与潜在问题

文章目录 一、ref的基本用法二、常见错误解析三、实例解析四、错误分析与解决五、注意事项六、总结 在React开发中,ref常用于访问DOM元素或组件实例。正确使用ref可以极大地提升用户体验,特别是在需要与DOM交互的场景中。然而,错误或不当的re…

奥运会Ⅷ--生成式人工智能的力量倍增器

生成式人工智能在商业领域的崭新时代 随着 OpenAI 的ChatGPT、Anthropic 的Claude和 Google 的Bard的推出,大规模文本分析和自然语言处理 (NLP) 的长期梦想瞬间成为现实。AI 不仅令人信服地通过了图灵测试,还催化了企业战略的范式转变。突然之间&#x…

8.5 day bug

bug1 没有适当的引号,引言就不是真正的引言 问了通义,原来用引言需要使用单引号括起来 bug2 没理解题意,挺好一网站可惜是英文的,顺便帮翻译还没反馈渠道帮… 问了通义,原来是要改变continueLoop的值 bug3 好家伙&a…

ts-node报错ERR_UNKNOWN_FILE_EXTENSION

问题 有个monorepo项目,在最外层一次性打包 3 个项目的脚本已经成功实现,如下: "build:test": "cross-env NODE_ENVtest vite build --mode test && esno ./build/script/postBuild.ts", "build:prod"…

一行代码实现图片懒加载?分享 1 段优质 HTML 代码片段!

本内容首发于工粽号:程序员大澈,每日分享一段优质代码片段,欢迎关注和投稿! 大家好,我是大澈! 本文约 700 字,整篇阅读约需 1 分钟。 今天分享一段优质 HTML 代码片段,只需一行代码…

MBD软件开发之数据管理

模块化开发中,模型集成和代码集成是很多工程师非常关心的问题。 常见的代码集成方式有两种,一是单元级模型上生成代码,在代码上做集成,一是模型集成之后,再去生成集成级别的代码。无论采用哪种方式,模型级…

网络端口转发

一. 如图网络拓扑 光猫改桥接之前光猫自身也会有一层局域网,光猫ip为局域网额的192.168.1.1 当改桥接之后,只有一层路由器的局域网,路由器为局域网的192.168.31.1 此时从公网对内网进行访问时,先访问到路由器的公网ip的某个端口…