首页 > 编程语言 >Java 中的异常

Java 中的异常

时间:2024-07-20 12:28:18浏览次数:10  
标签:语句 Java 抛出 try finally catch 异常

异常:就是出现的问题。

在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子句中的返回值。

标签:语句,Java,抛出,try,finally,catch,异常
From: https://blog.csdn.net/m0_46977298/article/details/140549995

相关文章

  • java Selenium,定位 伪元素.UI自动化
    Java中,要获取这个表单字段前面的星号“*”,因为是用的伪元素,无法直接通过常规定位获取字符,需要用到JavascriptExecutor。importorg.openqa.selenium.By;importorg.openqa.selenium.JavascriptExecutor;importorg.openqa.selenium.WebDriver;importorg.openqa.selenium.We......
  • 超详细的MySQL基本使用教程(1) 黑马程序员javaweb学习笔记+练习(附带idea新版ui图形化页
    什么是数据库MySQL概述数据模型关系型数据库SQL简介小结DDL-数据库的设计数据库的常见操作选中该语句然后点运行就成功运行了可以直接用图形化界面进行操作跳转到控制台表的常见操作1.创建练习在db01中创建这张表其中comment是鼠标悬停在......
  • 135java jsp SSM连锁店经营会员管理系统(源码+文档+任务书+运行视频+讲解视频)
     项目技术:SSM+Maven+Vue等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.tomcat环境:Tomcat7.x,8.x,9.x版本均可4.硬件环境:windows7/8/1......
  • 127java jsp SSM乡镇篮球队管理系统球队球员赛程管理(源码+文档+运行视频+讲解视频)
     项目技术:SSM+Maven+Vue等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.tomcat环境:Tomcat7.x,8.x,9.x版本均可4.硬件环境:windows7/8/1......
  • Java程序员转到仓颉开发可行吗
    Java程序员转到仓颉开发是可行的,但需要考虑多个因素,包括仓颉编程语言的特性、Java与仓颉之间的异同点、以及个人的技能储备和职业规划。仓颉编程语言的特性仓颉编程语言是华为公司自主研发的一款面向全场景智能的下一代应用编程语言。自主可控,仓颉编程语言没有基于任何现有......
  • 【JS逆向课件:第八课:异常处理】
    异常处理首先我们要理解什么叫做**"异常”**?在程序运行过程中,总会遇到各种各样的问题和错误。有些错误是我们编写代码时自己造成的:比如语法错误、调用错误,甚至逻辑错误。还有一些错误,则是不可预料的错误,但是完全有可能发生的:比如文件不存在、磁盘空间不足、......
  • JavaScript与DOM的奇妙探险:从入门到精通的实战笔记
    文章目录JavaScript基本说明特点两种使用方式在script中写使用script标签引入JS文件数据类型介绍特殊值运算符算数运算符赋值运算符逻辑运算符:![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/bbf5c150699845af837d3c45c926e941.png)条件运算符数组的定义基......
  • [0178]基于JAVA的产品配送智慧管理系统的设计与实现
    毕业设计(论文)开题报告表姓名学院专业班级题目基于JAVA的产品配送智慧管理系统的设计与实现指导老师(一)选题的背景和意义选题背景:随着电子商务和新零售行业的快速发展,产品配送已成为商业运营中不可或缺的重要环节。传统的配送管理模式往往存在信息更......
  • Java NIO 快速入门:Java 非阻塞 IO 编程详解
    一、NIO简介1.概述介绍:JavaNIO(NewInput/Output)是从Java1.4开始引入的一组新的IO库,旨在替代传统的阻塞式IO。NIO提供了更高效的IO操作,支持非阻塞模式和多路复用,适用于高并发场景。概述:NIO中通过Buffer作为缓存区,Channel作为数据通道来传输数据进行数据通讯,通过S......
  • [0182]基于JAVA的人事智慧管理系统专业版的设计与实现
    毕业设计(论文)开题报告表姓名学院专业班级题目基于JAVA的人事智慧管理系统专业版的设计与实现指导老师(一)选题的背景和意义选题背景与意义:随着社会经济的快速发展和企业规模的不断壮大,人力资源管理在企业管理中的地位日益凸显。传统的人事管理工作由......