人生在世皆有过错,来一起看看Java中的异常吧!!!

news2024/11/25 14:27:01

Java中的异常问题详解

一、异常的概念与分类

1.异常概念

概念:Java异常是一个描述在代码段中发生异常的对象,当发生异常情况时,一个代表该异常的对象被创建并且在导致该异常的方法中被抛出,而该方法可以选择自己处理异常或者传递该异常。

异常机制:异常机制是指当程序出现错误后,程序如何处理。具体来说,异常机制提供了程序退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器。

2.关于异常的分类

(1)非受查异常(运行时异常):是指程序在执行时出现的异常

举例Demo:

int[] array = null;
System.out.println(array.length);

//执行结果:
Exception in thread "main" java.lang.NullPointerException
	at TestDemo.main(TestDemo.java:160)
//必须对其进行捕获或声明以便抛出    

(2)受查异常(编译时异常):是指程序在进行编译时出现的异常

(3)逻辑错误:是指因为程序没有按照预期的逻辑顺序执行。异常也就是指程序运行时发生错误,而异常处理就是对这些错误进行处理和控制

3.常见的异常

(1)算术异常

Demo:

int a = 10;
System.out.println(a/0);


//执行结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
//0不能放在分母    

(2)数组越界异常

Demo:

int[] array = {1,2,3};
System.out.println(array[4]);


//执行结果:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 3

(3)空指针异常

Demo:

int[] array = null;
System.out.println(array.length);


//执行结果:
Exception in thread "main" java.lang.NullPointerException

二、异常的体系结构

在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性。

在这里插入图片描述

在图中可以看出

  • Throwable有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。异常和错误的区别是:异常能被程序本身可以处理,错误是无法处理。
  • Error指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表: StackOverflowError和OutOfMemoryError。
  • Exception是程序本身可以处理的异常。Exception 类有一个重要的子类 RuntimeException。RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。
  • Exception:分为运行时异常和非运行时异常。

三、异常的处理方式

1.防御式处理

防御式处理是指程序猿在写代码时就要有这种意识,写一步代码就会做一次检查。

如以下例子:

Demo:

boolean ret = false;
ret = 登陆游戏();
if (!ret) {
处理登陆游戏错误;
  return;
}
ret = 开始匹配();
if (!ret) {
处理匹配错误;
  return;
}
ret = 游戏确认();
if (!ret) {
处理游戏确认错误;
  return;
}
ret = 选择英雄();
if (!ret) {
  处理选择英雄错误;
  return;
}
ret = 载入游戏画面();
if (!ret) {
处理载入游戏错误;
  return;
}

2.事后认错型处理

事后认错型处理就是指先执行代码,如果遇到问题,再去处理问题。

(1).try···catch···异常捕获和处理

try {
  登陆游戏();
  开始匹配();
  游戏确认();
  选择英雄();
  载入游戏画面();
 ...
} catch (登陆游戏异常) {
  处理登陆游戏异常;
} catch (开始匹配异常) {
处理开始匹配异常;
} catch (游戏确认异常) {
处理游戏确认异常;
} catch (选择英雄异常) {
处理选择英雄异常;
} catch (载入游戏画面异常) {
处理载入游戏画面异常;
}

注:

  • try当中的存放可能出现的异常代码
  • catch当中捕获可能出现的异常

Demo:

try {
     int a = 10;
     System.out.println(a/0);

     System.out.println("正常代码!");
}catch (ArithmeticException e) {
      e.printStackTrace();//快速地定位异常出现的位置
      System.out.println("你这里出现了算术异常!");
}

//执行结果:
java.lang.ArithmeticException: / by zero
	at TestDemo.main(TestDemo.java:161)
你这里出现了算术异常!

从上面的结果可以看出,当代码运行到有错误的代码的时候,就会抛出异常,由catch去捕获异常,就不会继续执行后面正常的代码

关于try···catch···的使用细节

(1)如果try中出现了多个异常,当catch去捕捉时可用‘|’去分开各个异常.

catch (ArithmeticException | NullPointerException e)

(2)如果catch中没有写出对应的异常,这里就不会去捕获,最终这个异常就会交给JVM去处理,程序就会立即终止,正常的代码也不会执行.

(3)不会同时出现两个及以上异常

原因:因为当出现一个异常,就会直接被catch捕获,就不会继续执行try中的语句了.

(4)不建议这样写

catch(Exception e) {}

这样写说明你这人懒啊!!!

(5)try当中可能会同时抛出多个不同的异常对象,则必须用多个catch去捕获——多个异常,多次捕获.

(6)

catch(Exception e) {
            
}catch(ArithmeticException e) {
            
}

由于Exception是所有类的父类,那么后面的子类就没有存在的必要,所有这种写法不可行!!!

但是当父类Exception和子类交换位置时,这种写法是可行的.

(2)异常的声明

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

语法格式:

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

具体代码举例:

Demo:

public class TestDemo {
    public static void test(int a) throws CloneNotSupportedException {
        if (a == 10) {
            throw new CloneNotSupportedException();
        }
        System.out.println("异常后的代码不执行!");
    }
    public static void main(String[] args) {
        try {
            test(10);

            System.out.println("正常代码!");
        }catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

//执行结果:
java.lang.CloneNotSupportedException

注意事项:

  • throw必须写在方法体内部
  • 抛出的对象必须是Exception或者Exception子类的对象
  • 如果抛出的是Runtime Exception或者Runtime Exception的子类,则可以不用处理,交给JVM就行
  • 如果抛出的是编译异常,就必须处理,否则编译无法通过
  • 异常一旦抛出,异常后面的代码就不会执行

(3)关于finally关键字

finally:一般用于资源释放,断开连接,关闭管道流等

一般搭配try – catch --finally 或者 try — finally,一般来说无论try中是否抛出异常,都会执行finally。

Demo:

public class TestDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        try {
           int num = scanner.nextInt();
            System.out.println(num);
        }catch (InputMismatchException e) {
            e.printStackTrace();
            System.out.println("输入的数据不匹配!");
        }finally {
            System.out.println("执行了finally部分,一般用来关闭资源!");
            scanner.close();
        }
    }
}

在这里插入图片描述

这种就是正确的输入。

在这里插入图片描述

这种就是错误的输入,代码叫我们输入一个数字,但是这里我们输入了字符串,就会出现输入异常

但是finally部分的代码不管出现异常没有都会执行

(4)关于异常处理的流程

  • 如果try中有异常,就会抛出异常,由catch捕获,然后匹配是否有配对的异常
  • 如果有就执行catch中的语句
  • 如果没有就会将异常上传给上层调用者
  • 无论有没有都会执行finally中的语句
  • 如果上层调用者也没有,就会继续上传
  • 一直到main方法,如果main方法中也没有,就会将其交给JVM,此时程序机会异常终止

(5)finally的注意事项

建议不要在finally中return 数据!!!

因为finally 块中的 return 返回后方法结束执行,不会再执行 try 块中的 return 语句。也就是说try块中的return值会先保存起来,然后执行完finally中的代码后,才会把try块中的return值返回,所以finally中的代码逻辑是不会影响try块中的return值的。但如果在finally中使用return了就会导致try块中的代码得不到执行而无法返回正确的结果。

例子:

public class TestDemo {
    public static int func() {
        int num = 10;
        try{
            return num;
        }catch (Exception e){
            e.printStackTrace();
        } finally {
            num = 5;
            return num;
        }
    }
    public static void main(String[] args) {
        int ret = func();
        System.out.println(ret);
    }
}

//执行结果:
5

四、自定义异常

Java 中虽然已经内置了丰富的异常类, 但是并不能完全表示实际开发中所遇到的一些异常,此时就需要维护符合我
们实际情况的异常结构。

具体方式:

格式:public class XXXException extends Exception 或者 RuntimeException{

添加一个空参数的构造方法

添加一个带异常信息的构造方法

}

Demo举例:

class UserNameErrorException extends RuntimeException {
    public UserNameErrorException() {
        super();
    }
    public UserNameErrorException(String message) {
        super(message);
    }
}
class PassWordErrorException extends RuntimeException {
    public PassWordErrorException() {
        super();
    }
    public PassWordErrorException(String message) {
        super(message);
    }
}
public class TestDemo {
    private String userName = "admin";
    private String passWord = "123456";

    public void LoginInto(String userName,String passWord) {
        try {
            if(!this.userName.equals(userName)) {
                throw new UserNameErrorException("用户名错误!");
            }
            if (!this.passWord.equals(passWord)){
                throw new PassWordErrorException("密码错误!");
            }
            System.out.println("登陆成功!");
        }catch (UserNameErrorException e) {
            e.printStackTrace();
        }catch (PassWordErrorException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        TestDemo test = new TestDemo();
        test.LoginInto("admi","123456");
    }
}

第一种运行结果:当userName和passWord输入正确的时候

在这里插入图片描述

第二种运行结构:当userName和passWord其中有一个或者两个都不对的时候

在这里插入图片描述

在这里插入图片描述

注意事项:

  • 自定义异常通常会继承自 Exception 或者 RuntimeException
  • 继承自 Exception 的异常默认是受查异常
  • 继承自 RuntimeException 的异常默认是非受查异常

好啦!关于java中的异常就讲到这里,如果各位小伙伴有问题或者发现本博客有什么问题,可以私信哦!!!

以蝼蚁之行,展鸿鹄之志

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

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

相关文章

Invicti v23.5 for Windows 发布 - 企业应用安全测试

Invicti v23.5 for Windows - 企业应用安全测试 Invicti Standard 11 May 2023 v23.5.0.40516 请访问原文链接:https://sysin.org/blog/invicti/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org Invicti 是一种自动…

[HFCTF2022]ezchain

环境分析 环境提供了docker-compose.yml,nginx.conf文件,从两个文件中可疑分析出是不出网的环境 nginx.conf: server { listen 80;server_name localhost;location / {root /usr/share/nginx/html; #收到/路径请求会访问/usr/sha…

Keil5----Debug时,watch1中全局变量数值不刷新问题解决方法

问题: 在Keil5-MDK中,Debug时,watch1中全局变量数值不刷新。 解决方法: 步骤1:进入Debug模式 将程序调试下载器(STlink,Jlink,Ulink)连接,编译程序后。 进行如下操作&#xff1a…

算法修炼之练气篇——练气十六层

博主:命运之光 专栏:算法修炼之练气篇 前言:每天练习五道题,炼气篇大概会练习200道题左右,题目有C语言网上的题,也有洛谷上面的题,题目简单适合新手入门。(代码都是命运之光自己写的…

MySQL --- 多表查询

多表查询、事物、以及提升查询效率最有手段的索引 一. 多表查询 1.1 多表查询 --- 概述 1.1.1 数据准备 将资料中准备好的多表查询数据准备的SQL脚本导入数据库中。 部门表: 员工表: 1.1.2 介绍 多表查询:指从多张表中查询数据&#…

2023年的深度学习入门指南(13) - 写后端

2023年的深度学习入门指南(13) - 写后端 我们前面学习了用python在本机上写前端,也学习了使用HTML在本机写前端。同理,我们可以写Windows应用,mac应用,iOS应用,Android应用等等以适合各种终端。其实,最通用…

python+chrome rpc方式轻松绕过五秒盾(cloudflare)

Cloudflare 5秒盾是一种基于云技术的Web应用程序防火墙(WAF),旨在保护网站免受各种Web攻击,如SQL注入、跨站点脚本(XSS)和DDoS攻击。它能够在5秒内检测到并阻止恶意流量,并提供实时安全警报和日志记录。此外,它还提供了一系列安全功能,包括SSL / TLS加密、IP过滤、访问…

单链表你别再找我了,我怕双向链表误会

目录 带头双向循环链表的创建和初始化 创建一个新的结点(方便复用) 链表判空 链表打印 链表尾插 链表尾删 链表头插 链表头删 任意插入 任意删除 链表查找 链表销毁 完整代码 😎前言 之前我们讲了结构最简单,实现起来…

kettle win11 启动闪退 --启动日志

一、启动闪退 思路: 找原因找启动日志根据启动日志查看启动失败的原因 二、找启动日志 采用debug模式启动 查看控制台–根据控制台操作 看生成的启动日志文件 查看日志 DEBUG: Using PENTAHO_JAVA_HOME DEBUG: _PENTAHO_JAVA_HOMEE:\java8 DEBUG: _PENTAHO…

记一次靶场搭建与渗透测试

渗透目标 通过Windows7打入工作组环境,穿透两层内网拿到DC(域控制器)权限 环境搭建 环境搭建 网络拓扑 虚拟机网络配置 渗透测试 永恒之蓝外网打点 nmap -sS 192.168.2.0/24扫描外网存活主机,发现两台主机192.168.2.128和192…

芯片电源附近为什么放置的是0.1uF电容

日常使用情况 我们在电源滤波电路上可以看到各种各样的电容,100uF、10uF、100nF、10nF不同的容值,而在我们使用中常常会在芯片电源附近放置0.1uF电容,以TB67S109AFNG应用手册为例,其中推荐使用的也是0.1uF的电容 电容的特性 数字…

分享几款小白从零开始学习的会用到的工具/网站

大二狗接触编程也有两年了,差生文具多这大众都认可的一句话,在这里蹭一下这个活动分享一下从0开始学习编程有啥好用的工具 目录 伴侣一、Snipaste截图工具 伴侣二、Postman软件(可用ApiPost平替) 伴侣三、字体图标网站 伴侣四…

BlockChain-Account_TakeOver

题目描述 ECDSA 签名 假设我们的私钥为 d A d_A dA​而公钥为 Q A Q_A QA​, Q A d A ⋅ G Q_Ad_A\cdot G QA​dA​⋅G,接下来就是签名的过程,要签名的消息为 m m m 取 e H A S H ( m ) e HASH(m) eHASH(m)取 e e e的左边的 L n L_n L…

Baumer工业相机堡盟工业相机软件CameraExplorer常见功能使用说明二

Baumer工业相机堡盟工业相机软件CameraExplorer常见功能使用说明二 Baumer工业相机Baumer工业相机CE软件图像/视频存储功能Baumer工业相机CE软件记录日志文件功能Baumer工业相机CE软件查看图像Buffer及数据流统计信息 Baumer工业相机 Baumer工业相机堡盟相机是一种高性能、高质…

汇编五、伪指令与汇编程序结构

1、伪指令 1.1、概念 (1)伪指令是用于对汇编过程进行控制的指令,该类指令并不是可执行指令,没有对应机器码,只用于汇编过程中为汇编程序提供汇编信息,帮助编译器编译。 1.2、ASM51提供的伪指令 伪指令分为如下几类。 1.2.1、…

zuul源码分析

zuul源码解析 zuul与springboot整合的依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency>看到starter第一反应就是springboot的自动装配? 我们去…

简历制作、投递、(实习)面试技巧!!

目录 1.为什么要找实习 2.什么时候找实习 3.制作简历 4.简历注意事项 5.IT后端的校招的要求 6.简历里面写什么&#xff1f; 7.简历模板的选择 8.个人信息 9.求职意向 10.专业技能 11.项目经验 12.其他注意事项 13.找工作的手段 14.找工作的态度 ​编辑 15.面试…

IntelliJ IDEA 修改内存大小

idea有个配置文件&#xff0c;可以设置内存大小的&#xff0c;就跟咱的jvm的内存里面的堆大小&#xff0c;栈大小等等&#xff0c;可以设置的&#xff0c;而且设置了之后&#xff0c;你这个的性能就会得到提升。具体看下面怎么修改。 先说所要修改的文件 idea.vmoptions 的位置…

总结常见评价指标

整理一下在机器学习中常见的评价指标&#xff0c;包括&#xff1a; 混淆矩阵&#xff0c;TPR&#xff0c;FPR&#xff0c;TNR&#xff0c;FNR&#xff1b;Precision&#xff0c;Recall&#xff0c;Accuracy&#xff0c;F-score(F1-meature)ROC曲线&#xff0c;AUC&#xff1b; …

[Vue warn]: You may have an infinite update loop in a component render function

老板让该一个bug&#xff0c;结果一连出现好几个问题&#xff0c;然后报错也是很奇葩&#xff0c;在源代码上不能直接定位到&#xff0c;只知道在当前页面上出现的问题&#xff0c;弄了好久&#xff0c;给大家分享一下解决的经验&#xff1a; You may have an infinite update …