Java 中的异常

news2024/12/28 15:16:50

异常:就是出现的问题。

在Java中异常被当成对象进行处理,所有的异常类都继承于Throwable类,如果Java提供的异常类并不能满足需求,用户还可以自己定义一个异常类。

下面是异常体系结构:

7d1e2d697c3e4834a5cf8e0401abd22a.png

Throwable又分成了Error和Exception。本文仅讨论Exception及其子类,因为Error出现的话也不是我们能够处理的。

Exception又分为RuntimeException和其他异常。

由程序逻辑错误导致的异常属于RuntimeException体系异常,也叫不受查(unchecked)异常,并不需要进行异常处理,当然也可以处理并不会报错。比如以下几种常见的异常:

①错误的类型转换;

②数组索引越界;

③访问空指针。

而程序本身没有其他问题,由于像IO这类问题导致的异常属于其他异常,也叫受查(checked)异常,必须显示地进行异常处理(捕获或者抛出异常),否则会报错。比如以下这种情况:

①读取本地不存在的文件。

②网络断开连接。

当出现异常时有两种解决方式:

1、捕获异常进行处理,即try - catch捕获异常。

2、将异常传递给方法调用者,即抛出异常。

如果调用了一个抛出异常的方法,那么必须进行处理或传递,如何选择呢?

如果知道如何处理的异常可以进行捕获,而那些不知道怎样处理的异常继续向上抛出。

向上抛出

什么时候需要向上抛出异常?

(1)传递一个危险信号,需要让调用者知道;

(2)本方法没有处理异常的能力,方法调用者有能力处理;

(3)抛出是框架层面的选择。

这里介绍一下JVM默认的异常处理方式:

①结束程序的运行,即异常下面的代码就不会执行了;

②将异常信息、异常原因和异常位置以红色字体输出在控制台。

什么是抛出异常?

1、throws

  • 在方法的后面使用throws关键字将可能会抛出的异常进行声明,表示此方法不处理异常,一旦发生异常会将异常进行抛出,交由方法的调用处进行处理。

具体格式如下:

public Image loadImage(String s) throws IOException {

}

2、throw

  • 使用关键字 throw 手动抛出一个异常,即手动进行异常类对象的实例化操作。
throw new EOFException();

关于throws和throw两个的细节:

  1. 都是抛出异常,可同时使用,也可单独使用;
  2. 都将异常传递给方法的调用者;
  3. 都会结束当前方法中剩余代码的执行。

捕获异常

使用try-catch语句。捕获单个异常格式如下:

try {     
    编写可能会出现异常的代码
} catch (异常类型  e)
{     
    处理异常的代码     //记录日志/打印异常信息/继续抛出异常
}

在一个try语句块中可以捕获多个异常类型,并对不同类型的异常做出不同的处理。可以按照下列方式为每个异常类型使用一个单独的catch子句:

try{
     编写可能会出现异常的代码
}catch(FileNotFoundException e) {  //当try中出现FileNotFoundException 类型异常,就用该catch来捕获
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
}catch(UnknownHostException e) {  //当try中出现UnknownHostException 类型异常,就用该catch来捕获
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
}

注意多个catch语句中的异常类型不能一样,并且父类的异常应该放在子类的后面,否则会报错,因为如果写在最前面的话,异常在第一个岔路口就被抓住了,后面的捕获就多余了,依据Java的严谨性,不允许出现这种情况。

而且异常对象可能包含与异常本身有关的信息。要想获得对象的更多信息,可以试着使用e.getMessage()或者e.printStackTrace()得到详细的错误信息(如果有的话),或者使用 e.getClass().getName() 得到异常对象的实际类型。

在Java SE7中,同一个 catch 子句中可以捕获多个异常类型,中间用 | 进行隔开。例如,假设对应缺少文件和未知主机异常的动作是一样的,就可以合并catch子句:

try {
    编写可能会出现异常的代码
} catch (FileNotFoundException| UnknownHostException e) {
    处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
} catch(I0Exception e) {
    处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
}

那么什么时候抛出异常?什么时候捕获异常呢?

解释1

一句话回答就是“没有金刚钻,不揽瓷器活”。

如果你发现了某个问题,你又没能力解决,你就该汇报给上级,这就是【抛出异常】。

如果你接到了下属汇报的问题,你也没能力解决,你就只好再汇报给你的上级,这就是【继续抛出】。

只有你有能力解决的情况下,你才可以把这个问题解决掉,这就是【捕获异常】。

总结就是:谁遇到困难,谁抛出异常。谁解决问题,谁捕获异常。

下层抛出上层进行捕获。

细节1:

如果一个异常没有在任何地方被捕获,那么就会由虚拟机调用默认的异常处理机制,结束程序的运行,并在控制台打印异常有关信息。

前面还没懂吗,你不用throw抛出异常,调用者就接收不到异常,就无法捕获异常并处理,最后会交给虚拟机处理,这样程序就会停止运行,之后的代码无法运行。

给出一个代码例子: 

public class test05 {
    public static void main(String[] args) {
        int[] arr = null;
        try {
            int max = getMax(arr);
        } catch (NullPointerException e) {
            System.out.println("空指针异常");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("索引越界异常");
        }
    }
    public static int getMax (int[] arr) throws NullPointerException, ArrayIndexOutOfBoundsException{
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        return max;
    }
}

finally

不论是否有异常被捕获,finally子句都将被执行。比如打开了一些资源,但是异常发生时,希望这些文件可以关闭,就可以使用finally。下面举一个例子,其中的1,2...表示代码:

InputStream in = new FileInputStream(...);
try {
    // 1
    code that throw exceptions
    // 2
} catch {
    // 3
    show error message
    // 4
} finally {
    // 5 
    in.close();
}
// 6

1、try语句中是否有异常发生? 

①try语句中没有异常发生。那么try语句中的所有代码都会被执行,然后执行finally语句中的所有代码,接着执行finally后面的代码,即执行标注的1,2,5,6。

2、try语句中有异常发生,但是catch语句是否可以捕获?

(1)try语句中发生一个可以由catch语句捕获的异常,而catch语句中是否又抛出了异常?

①catch语句中没有抛出了异常。首先会执行try语句中异常发生之前的代码,然后执行catch语句中的所有代码,接着是finally语句中的所有代码,最后执行finally后面的代码,即执行标注的1,3,4,5,6。

②catch语句抛出了异常。还会执行finally子句吗?必须执行,要不然finally还有什么用呢,就是不会实现finally子句后面的语句了,结束方法的运行。即1,3,5。

警告:当 finally 子句包含return语句时,将会出现一种意想不到的结果。假设使用return语句从try语句块中退出。在方法返回前,finally子句的内容将被执行。如果 finally 子句中也有一个return语句,这个返回值将会覆盖原始的返回值。下面是一个例子:

public static int f(int n) {
    try {
        int r= n* n;
        return r;
    } 
    finally {
        if(n == 2)
            return 0;
    }
}

如果调用f(2),那么 try语句块的计算结果为r=4,并执行return 语句。然而,在方法真正返回前,还要执行 finally 子句。finally 子句将使得方法返回 0,这个返回值覆盖了原始的返回值 4。

总结就是:假如try和finally子句中都带有return返回值,最终会返回finally子句中的返回值。

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

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

相关文章

《无所不能的JavaScript · 对象简介》

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

OpenStack Yoga版安装笔记(七)glance练习补充

1、练习场景说明 在OpenStack Yoga版安装笔记&#xff08;五&#xff09;中&#xff0c;glance已经在controller node虚拟机上安装完成&#xff0c;并且已经成功拍摄了快照。 此时&#xff0c;controller node虚机已经安装了keystone、keystone DB、glance、glance DB、OpenSta…

利用【MATLAB】和【Python】进行【图与网络模型】的高级应用与分析】

目录 一、图与网络的基本概念 1. 无向图与有向图 2. 简单图、完全图、赋权图 3. 顶点的度 4. 子图与连通性 5. 图的矩阵表示 MATLAB代码实例 Python代码实例 二、最短路径问题 1. 最短路径问题的定义 2. Dijkstra算法 MATLAB代码实例 Python代码实例 三、最小生…

昇思MindSpore学习总结十七 —— 基于MindSpore通过GPT实现情感分类

1、要求 2、导入了一些必要的库和模块 以便在使用MindSpore和MindNLP进行深度学习任务时能使用各种功能&#xff0c;比如数据集处理、模型训练、评估和回调功能。 import os # 导入操作系统相关功能的模块&#xff0c;如文件和目录操作import mindspore # 导入MindSpore库&a…

入门C语言只需一个星期(星期六)

点击上方"蓝字"关注我们 01、创建结构体 struct MyStructure { // 结构声明 int myNum; // 成员&#xff08;int 变量&#xff09; char myLetter; // 成员&#xff08;char 变量&#xff09;}; // 用分号结束结构创建一个名为 s1 的结构变量​struct myStru…

# Redis 入门到精通(九)-- 主从复制(1)

Redis 入门到精通&#xff08;九&#xff09;-- 主从复制&#xff08;1&#xff09; 一、redis 主从复制 – 主从复制简介 1、互联网“三高”架构 高并发高性能高可用 2、你的“Redis”是否高可用&#xff1f; 1&#xff09;单机 redis 的风险与问题 问题1.机器故障  现…

kafka服务介绍

kafka 安装使用管理 Kafka Apache Kafka 是一个开源的分布式事件流平台&#xff0c;主要用于实时数据传输和流处理。它最初由 LinkedIn 开发&#xff0c;并在 2011 年成为 Apache 基金会的顶级项目。Kafka 设计的目标是处理大规模的数据流&#xff0c;同时提供高吞吐量、低延迟…

C语言 通讯录管理 完整代码

这份代码&#xff0c;是我从网上找的。目前是能运行。我正在读。有些不懂的地方&#xff0c;等下再记录下来。 有些地方的命名&#xff0c;还需要重新写一下。 比如: PersonInfo* info &address_book->all_address[address_book->size]; 应该改为&#xff1a; Perso…

C#实现数据采集系统-实现功能介绍

系统介绍 我们这里主要使用C#( .Net 6)来实现一个数据采集系统&#xff0c;从0到1搭建数据采集系统&#xff0c;从系统分析&#xff0c;功能拆解&#xff0c;到一一实现 数据采集 数据采集是企业信息化和数字化转型过程中的关键环节&#xff0c;它涉及到从生产设备、传感器…

Microsoft Visual C++ 2010 Express 使用

Microsoft Visual C 2010 Express 使用 Microsoft Visual C 2010 Express&#xff08;简称VC 2010 Express&#xff09;是一款免费的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为C和C语言的开发者设计。 安装 下载|本站链接【VC2010简体中文版】的安装包并解压…

2024年新手卖家该如何做好亚马逊运营?

随着电子商务的蓬勃发展&#xff0c;越来越多的新手卖家选择在亚马逊这一国际电商巨头平台上开展业务。然而&#xff0c;想要在竞争激烈的市场中脱颖而出&#xff0c;新手卖家需要精心规划并执行有效的运营策略。以下是为2024年新手卖家提供的关于如何做好亚马逊运营的一些建议…

C#学习-刘铁猛

文章目录 1.委托委托的具体使用-魔板方法回调方法【好莱坞方法】&#xff1a;通过委托类型的参数&#xff0c;传入主调方法的被调用方法&#xff0c;主调方法可以根据自己的逻辑决定调用这个方法还是不调用这个方法。【演员只用接听电话&#xff0c;如果通过&#xff0c;导演会…

刷题笔记 739. 每日温度 (单调栈),215. 数组中的第K个最大元素(堆),347.前 K 个高频元素

739. 每日温度 &#xff08;单调栈&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/daily-temperatures/description/?envTypestudy-plan-v2&envI…

Fast Planner规划算法(一)—— Fast Planner前端

本系列文章用于回顾学习记录Fast-Planner规划算法的相关内容&#xff0c;【本系列博客写于2023年9月&#xff0c;共包含四篇文章&#xff0c;现在进行补发第一篇&#xff0c;其余几篇文章将在近期补发】 一、Fast Planner前端 Fast Planner的轨迹规划部分一共分为三个模块&…

Haproxy服务

目录 一.haproxy介绍 1.主要特点和功能 2.haproxy 调度算法 3.haproxy 与nginx 和lvs的区别 二.安装 haproxy 服务 1. yum安装 2.第三方rpm 安装 3.编译安装haproxy 三.配置文件详解 1.官方地址配置文件官方帮助文档 2.HAProxy 的配置文件haproxy.cfg由两大部分组成&…

React+TypeScript 组件库开发全攻略:集成Storybook可视化与Jest测试,一键发布至npm

平时我除了业务需求&#xff0c;偶尔会投入到UI组件的开发中&#xff0c;大多数时候只会负责自己业务场景相关或者一小部分公共组件&#xff0c;极少有从创建项目、集成可视化、测试到发布的整个过程的操作&#xff0c;这篇文章就是记录组件开发全流程&#xff0c;UI组件在此仅…

RabbitMQ学习实践二:MQ的实现

文章是本人在学习springboot实现消息队列功能时所经历的过程的记录&#xff0c;仅供参考&#xff0c;如有侵权请随时指出。 参考文章地址&#xff1a; RabbitMQ安装与入门_rabbitmq win11配置-CSDN博客 RabbitMQ入门到实战一篇文章就够了-CSDN博客 RabbitMQ系列&#xff08…

AI跟踪报道第48期-新加坡内哥谈技术-本周AI新闻:Open AI 和 Mistral的小型模型

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

华为路由器SSH登录实验

概念 SSH全称安全外壳&#xff08;Secure Shell&#xff09;协议&#xff0c;这个协议的目的就是为了取代缺乏机密性保障的远程管理协议&#xff0c;SSH基于TCP协议的加密通道&#xff0c;让客户端使用服务器的RSA公钥来验证SSHv2服务器的身份。 创建密钥对 在充当SSH服务器的…

UE4-获得角色控制权的两种方法

方法一&#xff1a; 方法二&#xff1a; 注意此方法不能有多个玩家出生点&#xff0c;如果有多个玩家出生点&#xff0c;会随机的选择一个玩家出生点进行生成。