Java异常类

news2024/9/20 14:31:58

目录

Java异常类

Java中的异常体系

抛出异常

处理异常

处理异常的两种方式

try...catch和throws的区别

finally关键字

抛出异常注意事项

自定义异常类


Java异常类

Java中的异常体系

在Java中,异常类的父类为Throwable类,在Throwable下,存在两个子类:

  1. Error类:错误类,一般错误类中的错误都是致命错误,例如栈溢出错误StackOverflowError
  2. Exception类:异常类,一般是小型错误,例如数组越界ArrayIndexOutofBoundException

一般情况下Exception类是编译时异常,但是其中有一个特殊的异常RuntimeException,该异常为运行时异常,例如数组越界异常就属于RuntimeException

上面的体系可以参考下图:

抛出异常

在Java中,使用throw关键字抛出异常对象,基本格式如下:

throw new 异常类(<可选打印信息>);

例如下面的代码:

public class Test {
    public static void main(String[] args) {
        String s = "test.txt";
        method(s);
    }

    public static void method(String s) {
        if(!s.endsWith(".txt")) {
            throw new FileNotFoundException("文件不存在");
        }
        else {
            System.out.println("文件存在");
        }
    }
}

处理异常

处理异常的两种方式

在Java中一共有两种处理异常的方式:

  1. 使用throws关键字抛出当前方法中的异常,如果一个方法有多个异常抛出,可以使用,分隔不同的异常类,使用格式如下:
方法(形参列表) throws 异常类名1, 异常类2... {
    // 方法体
    throw new 异常对象名();
}

// 例如
public static void method(String s) throws FileNotFoundException {
    if(!s.endsWith(".txt")) {
        throw new FileNotFoundException("文件不存在");
    }
    else {
        System.out.println("文件存在");
    }
}
  1. 使用try...catch捕获异常,使用try包裹可能出现异常的语句,catch捕获异常对象,catch语句可以不止一个,基本格式如下:
try{
    // 可能出现异常的语句
}
catch(异常类 异常对象名)
{
    // 处理语句
}
// 可以有多个catch语句

例如下面的代码:

public class Test {
    public static void main(String[] args) {
        String s = "test.txt1";
        try {
            method(s);
        } catch (FileNotFoundException e) {
            System.out.println(e);
            // 也可以使用下面的方式打印完整信息
            // e.printStackTrace();
        }
    }

    public static void method(String s) throws FileNotFoundException {
        if (!s.endsWith(".txt")) {
            throw new FileNotFoundException("文件不存在");
        } else {
            System.out.println("文件存在");
        }
    }
}

在处理异常时,如果抛出的异常类是另一个异常类的子类,那么可以使用throws向上抛出对应父类异常类,例如上面的FileNotFoundException属于父类IOException,所以可以抛出IOException或者Exception

同样,对于try...catch语句也是如此

public class Test {
    public static void main(String[] args) {
        String s = "test.txt1";
        try {
            method(s);
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public static void method(String s) throws IOException {
        if (!s.endsWith(".txt")) {
            throw new FileNotFoundException("文件不存在");
        } else {
            System.out.println("文件存在");
        }
    }
}

如果可能出现的异常语句在try中确实出现了异常,则当前try中出现异常的语句之后的语句不会再执行,否则正常执行,例如下面的代码:

public class Test {
    public static void main(String[] args) {
        String s = "test.txt1";
        try {
            method(s);
            System.out.println("出现异常时我不会出现");
        } catch (FileNotFoundException e) {
            System.out.println(e);
        }
    }

    public static void method(String s) throws IOException {
        if (!s.endsWith(".txt")) {
            throw new FileNotFoundException("文件不存在");
        } else {
            System.out.println("文件存在");
        }
    }
}

输出结果:
java.io.FileNotFoundException: 文件不存在

try...catchthrows的区别

使用throws处理异常时,第一个出现异常的位置开始抛出异常,此时该方法不再执行剩余的代码,将异常向方法调用处抛,如果方法调用处依旧没有处理异常,则继续向上抛出,以此类推,如果最后一个调用处依旧没有处理,则此时JVM就会报错,打印对应的异常信息

使用try...catch处理异常时,如果catch可以捕获到try中的异常,则代表异常被正常处理,此时其他的catch将不会被执行(即从上而下依次匹配直到遇到合适的),但是不可以将父类异常放在子类异常前,否则编译报错,当正常处理完异常后,try...catch后面的语句将正常执行

finally关键字

finally关键字用于一定要执行的代码,放在最后一个catch之后,有了finally后,不论是否出现了异常,都会走finally中的语句,除非在可以捕获到对应异常的catch语句中使用了System.exit(0)(结束JVM虚拟机运行),例如下面的代码:

public class Test {
    public static void main(String[] args) {
        String s = "test.txt1";
        try {
            method(s);
            System.out.println("出现异常时我不会出现");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("必须要执行我");
        }
    }

    public static void method(String s) throws IOException {
        if (!s.endsWith(".txt")) {
            throw new FileNotFoundException("文件不存在");
        } else {
            System.out.println("文件存在");
        }
    }
}

输出结果:
java.io.FileNotFoundException: 文件不存在
    at com.epsda.advanced.test_exception.Test.method(Test.java:30)
    at com.epsda.advanced.test_exception.Test.main(Test.java:18)
必须要执行我



// 如果加了System.exit(0)
public class Test {
    public static void main(String[] args) {
        String s = "test.txt1";
        try {
            method(s);
            System.out.println("出现异常时我不会出现");
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(0); 使用 System.exit(0) 退出程序,此时finally也不会执行
        } finally {
            System.out.println("必须要执行我");
        }
    }

    public static void method(String s) throws IOException {
        if (!s.endsWith(".txt")) {
            throw new FileNotFoundException("文件不存在");
        } else {
            System.out.println("文件存在");
        }
    }
}

输出结果:
java.io.FileNotFoundException: 文件不存在
    at com.epsda.advanced.test_exception.Test.method(Test.java:30)
    at com.epsda.advanced.test_exception.Test.main(Test.java:18)

一般使用finally在关闭资源时,因为部分情况下GC(垃圾回收器)无法回收堆内存中的文件,从而无法释放内存,此时需要在finally中手动关闭资源

抛出异常注意事项

  1. 如果父类方法已经抛出了异常,子类重写父类对应的方法就可以不再抛出异常
  2. 如果父类方法没有抛出异常,子类重写父类对应的方法就不要抛出异常

例如下面的代码:

// 父类方法不抛出异常,但子类对应的重写方法抛出异常
public class Test1 {
    public static void main(String[] args) {

    }

    class A {
        public void method() {

        }
    }

    class B extends A {
        @Override
        public void method() throws Exception{

        }
    }
}

输出结果:
overridden method does not throw java.lang.Exception

自定义异常类

如果想要自定义一个异常类,则自定义的类就必须继承自Exception,否则编译器不会将其当作异常类,格式如下:

public class 自定义异常类名 extends Exception {
    // 内容
}

例如下面的代码:

// 自定义异常类
public class LoginFailException extends Exception{
}

// 测试
public class Test2 {
    public static void main(String[] args) {
        String name = "admin";
        String password = "123456";
        try {
            login(name, password);
        } catch (LoginFailException e) {
            e.printStackTrace();
        }
    }

    public static void login(String name, String password) throws LoginFailException{
        if(!name.equals("admin") || !password.equals("123456")){
            throw new LoginFailException();
        }
    }
}

如果想添加自定义异常信息,需要提供一个有参构造函数,该构造函数使用一个String类型的message构造对象,此时会调用父类的构造函数,因为Exception类中存在对应的构造函数

// 自定义异常类
public class LoginFailException extends Exception{
    public LoginFailException() {
    }

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

// 测试
public class Test2 {
    public static void main(String[] args) {
        String name = "admin";
        String password = "123456";
        try {
            login(name, password);
        } catch (LoginFailException e) {
            e.printStackTrace();
        }
    }

    public static void login(String name, String password) throws LoginFailException{
        if(!name.equals("admin") || !password.equals("123456")){
            throw new LoginFailException("登录失败");
        }
    }
}

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

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

相关文章

git submodule子模块的使用

子模块的使用 添加子模块 添加子模块 git submodule add <子仓库URL> <子仓库路径> 例子&#xff1a; git submodule add http://192.168.100.181/guideir/poco.git 3rdparty/poco 若子模块存在好几个分支&#xff0c;可以在添加子模块时&#xff0c;指定分支 g…

全国糖酒会,就这5个字。“会天下美味”

“全国糖酒会&#xff0c;会天下美味”&#xff0c;是全国糖酒会的品牌口号。这个品牌口号来的非常偶然。 两年前&#xff0c;全国糖酒会准备更新标志之时&#xff0c;也设计了一个品牌口号。新标志发布前几天&#xff0c;临时作了调整&#xff0c;最终变成了“全国糖酒会&…

Day92 代码随想录打卡|动态规划篇---斐波那契数

题目&#xff08;leecode T509&#xff09;&#xff1a; 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n)…

C++11线程池、多线程编程(附源码)

Test1 示例源码展示&#xff1a; #include<iostream> #include<thread> #include<string> using namespace std;void printHelloWord(string s) {cout << s << endl;//return; } int main() {string s;s "wegfer";thread thread1(p…

【动手学深度学习】08 线性回归 + 基础优化算法(个人向笔记)

1. 线性回归 一个简化的模型&#xff1a; 我们可以这样来定义线性模型&#xff1a;注意这里先转置变成了列向量线性模型可以被看成时一个单层的神经网络&#xff1a;单层是因为单层参数 - 用一个函数来衡量预估质量&#xff1a;损失函数 在训练的时候寻找最小化的损失的参数 w…

Vivado编译报错黑盒子问题

1 问题描述 “Black Box Instances: Cell **** of type ** has undefined contents and is considered a back box. The contents of this cell must be defined for opt_design to complete successfully.” 检查工程代码提示的模块&#xff0c;该模块为纯手写的Veril…

使用AI赋能进行软件测试-文心一言

1.AI赋能的作用 提高速度和效率缺陷预测与分析 2.AI互动指令格式--文心一言 角色、指示、上下文例子、输入、输出 a 直接问AI 针对以下需求&#xff0c;设计测试用例。 需求&#xff1a; 1、账号密码登录系统验证账号和密码的正确性。 验证通过,用户登录成功,进入个人中心;验…

【优选算法】---前缀和

前缀和 一、【模板】一维前缀和二、【模板】二维前缀和三、寻找数组的中心下标四、除自身以外数组的乘积五、和为K子数组六、和可被 K 整除的子数组七、连续数组八、矩阵区域和 一、【模板】一维前缀和 一维前缀和&#xff0c;链接 1、预处理出来一个前缀和数组 注意&#xf…

C#学习 深入理解委托、匿名方法、Lamda表达式、Linq;

目录 一.委托 1.1 什么是委托 1.2 委托的使用 二.匿名方法和Lamda表达式 2.1 什么是匿名方法 2.2 Lambda表达式 三.Linq 3.1 Linq理解 3.2 Linq的扩展方法 一.委托 1.1 什么是委托 委托和类一样&#xff0c;是具有特定参数列表和返回值类型的方法函数的…

VSCode连接docker

1.启动ssh服务 vim /root/.bashrc 或者 vim ~/.bashrc /usr/sbin/sshd #启动ssh服务~代表主目录&#xff0c;cd ~会返回root目录 cd / 返回最根上的目录 为了防止每次打开容器都要输入此指令&#xff0c;我们直接在 ~/.bashrc文件最后一行添加sshd启动命令即可。 打开终端…

javase小项目--图书管理系统

前面我们已经学习到了javase的基本语法结构-继承&#xff0c;多态&#xff0c;接口&#xff0c;接下来就让我们大家一起来利用这些来手动实现一个小项目——简洁的图书管理系统 目录 1.思路 1.book类 1.book 2.booklist 2.user类 user AdminUser NormalUser 3.ioperat…

如何使用Pytorch-Metric-Learning?

文章目录 如何使用Pytorch-Metric-Learning&#xff1f;1.Pytorch-Metric-Learning库9个模块的功能1.1 Sampler模块1.2 Miner模块1.3 Loss模块1.4 Reducer模块1.5 Distance模块1.6 Regularizer模块1.7 Trainer模块1.8 Tester模块1.9 Utils模块 2.如何使用PyTorch Metric Learni…

传统CV算法——基于harris检测算法实现角点检测

角点 角点是图像中的一个特征点&#xff0c;指的是两条边缘交叉的点&#xff0c;这样的点在图像中通常表示一个显著的几角。在计算机视觉和图像处理中&#xff0c;角点是重要的特征&#xff0c;因为它们通常是图像中信息丰富的区域&#xff0c;可以用于图像分析、对象识别、3D…

JavaScript 循环控制语句-break和continue

break循环 首先i0&#xff0c;判断i是否<5,满足条件&#xff0c;判断i是否等于3&#xff0c;i不等于3&#xff0c;输出i0&#xff0c;i的值加1&#xff0c;判断i是否<5&#xff0c;判断i是否等于3&#xff0c;i不等于3&#xff0c;输出i1&#xff0c;i的值加1&#xff0c…

【H2O2|全栈】关于HTML(6)HTML基础(五 · 完结篇)

HTML基础知识 目录 HTML基础知识 前言 准备工作 标签的具体分类&#xff08;五&#xff09; 本文中的标签在什么位置中使用&#xff1f; 表单&#xff08;二&#xff09; 下拉选择菜单 文本域 案例 拓展标签 iframe框架 案例 预告和回顾 后话 前言 本系列博客介…

EasyExcel模板导出与公式计算(下)

目录 环境要求 功能预览 需求分析 导入依赖 制作模板 编写代码 格式优化 最终效果 总结 在上一篇 EasyExcel模板导出与公式计算&#xff08;上&#xff09;-CSDN博客 文章中我们知道了在若依中使用自带的Excel注解来实现表格数据的导出&#xff0c;并且通过重写相关接…

C++复习day07

一、继承 1.什么是继承&#xff1f;继承的意义是什么&#xff1f; 继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c…

C++ STL 适配器

系列文章目录 模板特例化&#xff0c;偏特化&#xff0c;左右值引用 https://blog.csdn.net/surfaceyan/article/details/126794013 C STL 关联容器 https://blog.csdn.net/surfaceyan/article/details/127414434 C STL 序列式容器(二) https://blog.csdn.net/surfaceyan/arti…

项目实战系列三: 家居购项目 第四部分

购物车 &#x1f333;购物车&#x1f346;显示购物车&#x1f346;更改商品数量&#x1f346;清空购物车&&删除商品 &#x1f333;生成订单 &#x1f333;购物车 需求分析 1.会员登陆后, 可以添加家居到购物车 2.完成购物车的设计和实现 3.每添加一个家居,购物车的数量…

比较顺序3s1,3s2,4s1之间的关系

(A,B)---6*30*2---(0,1)(1,0) 分类A和B&#xff0c;让B全是0。当收敛误差为7e-4&#xff0c;收敛199次取迭代次数平均值&#xff0c;3s1为 3s2为 4s1为 3s1&#xff0c;3s2&#xff0c;4s1这3个顺序之间是否有什么联系 &#xff0c; 因为4s1可以按照结构加法 变换成与4s1内在…