Javase-异常

文章目录

    • 1. 异常概述
    • 2. 异常的继承结构
    • 3. 自定义异常
    • 4. 异常的处理
    • 5. 异常的使用
    • 6. finally语句块
    • 7. 方法覆盖与异常

1. 异常概述

什么是异常

①什么是异常?有什么用?
1.Java中的异常是指程序运行时出现了错误或异常情况,导致程序无法继续正常执行的现象。例如,数组下标越界,空指针异常,类型转换异常等都属于异常情况,
2、 Java提供了异常处理机制,即在程序中对可能出现的异常情况进行捕捉和处理。异常机制可以帮助程序员更好地管理程序的错误和异常情况,避免程序崩溃或出现不可预测的行为。
3.没有异常机制的话,程序中就可能会出现一些难以调试和预测的异常行为,可能导致程序崩溃,甚至可能造成数据损失或损害用户利益。因此,异常机制是一项非常重要的功能,是编写可靠程序的基础。

异常的存在形式

一句话总结, Java当中异常以类和对象的方式存在, 让我们看下面这一段代码

public class Main
	public static void main(String[] args){
			String s = null;
			System.out.print(s.toString());
		}
	}
}

上述代码明显发生了一个著名的异常 – 空指针异常
在这里插入图片描述
那这个异常的底层到底是如何发生的呢, 其实质上是new 了一个空指针异常的对象然后抛出

public class Main
	public static void main(String[] args){
			//由于这个运行时异常没有被捕获, 所以直接导致了JVM的终止运行
			throw new NullPointerException();
		}
	}
}

2. 异常的继承结构

异常的继承结构详解

①所有的异常和错误都是可抛出的,都继承了Throwable类。
②Error是无法处理的,出现后只有一个结果:JVM终止。
③Exception是可以处理的。
④Exception的分类

  1. 所有的RuntimeException的子类:运行时异常/未检查异常(UncheckedException)/非受控异常
  2. Exception的子类(除RuntimeException之外):编译时异常/检查异常(CheckedException)/受控异常

⑤编译时异常和运行时异常区别:

  1. 编译时异常特点;在编详阶段必须提前处理,如果不处理编详器报错。
    运行时异常特点;在编译阶段可以选择处理,也可以不处理,没有硬性要求。
  2. 编译时异常一般是由外部环境或外在条件引起的,如网络故障,磁盘空间不足。文件找不到等
    运行时异常一般是由程序员的错误引起的,并且不需要强制进行异常处理

为什么有编译时异常的这个说法

注意:编译时异常并不是在编译阶段发生的异常,所有的异常发生都是在运行阶段的,因为每个异常发生都是会new异常对象的,new异常对象只能在运行阶段完成。那为什么叫做编译时异常呢?这是因为这种异常必须在编译阶段提前预处理,如果不处理编译器报错,因此而得名编译时异常。

图解异常的继承结构
下面我们用starUML工具画一下异常继承体系的简图
(其实异常的机构体系十分庞大, 我们的这个图只是举了几个类作为示例)
在这里插入图片描述

3. 自定义异常

自定义异常的方法就两步

  1. 编写一个异常类继承Exception或者是RuntimeException(原则就是判断是程序员的错还是其他)
  2. 给两个构造方法, 一个无参的, 一个带有一个String参数, 调用父类的构造方法
    这个方法的灵感其实来源于源码, 上面我们的UML类继承图也指出, 其实异常继承机构中真正起作用的是Throwalbe方法

下面我们给出例子

/**
 * 年龄非法异常类
 */
public class IllegalAgeException extends Exception{
    
    //无参数的构造方法
    public IllegalAgeException(){
        super();
    }
    
    //带有一个参数String的构造方法
    public IllegalAgeException(String message){
        super(message);
    }
}
/**
 * 名字非法异常类
 */
public class IllegalNameException extends Exception{
    //无参数的构造方法
    public IllegalNameException() {
        super();
    }

    //带有一个参数String的构造方法
    public IllegalNameException(String message) {
        super(message);
    }
}

完成下面的业务逻辑

自定义异常
①定义两个编译时异常:
IlegalNameException:无效名字异常
IllegallAgeException:无效年龄异常
②完成这样的需求:
1.编写一个用户注册的方法,该方法接收两个参数,一个是用户名,一个是年龄。如果用户名长度在6-12]位,并且年龄大于18岁时,输出用户注册成功。
2.如果用户名长度不是[6-12)位时,让程序出现异常,让llegalNameException异常发生!如果年龄小于18岁时,让程序出现异常,让llegalAgeException异常发生!

下面是我们的实现的代码, 我们先通过throws把异常都抛出给上级

import powernode.exception.IllegalAgeException;
import powernode.exception.IllegalNameException;

import java.util.Scanner;

/**
 * 测试的主程序
 *  本次测试中我们的异常机制强行抛给了Main函数来处理
 *  而Main函数又上抛给虚拟机JVM进行处理, 而JVM的处理机制就是直接断掉测试程序
 */
class ExceptionTest{
    public static void main(String[] args) throws IllegalNameException, IllegalAgeException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入名字 : ");
        String name = sc.next();
        System.out.println("请输入年龄 : ");
        int age = sc.nextInt();
        UserService userService = new UserService();
        userService.register(name,age);
    }
}

/**
 * 下面是用户层, 用于接收用户的处理请求
 */
public class UserService {
    public void register(String name, int age)  throws IllegalAgeException, IllegalNameException {
        System.out.println("当前用户正在注册...");
        Sql sql = new Sql();
        sql.save(name,age);
        System.out.println("注册任务已完成...");
    }
}

/**
 * 下面是数据库层, 用来连接数据库, 在数据库中保存相关的用户信息
 */
class Sql {
    public void save(String name, int age) throws IllegalAgeException, IllegalNameException {
        //在这里对传入的参数进行处理操作
        if (name.length() < 6 || name.length() > 12) {
            throw new IllegalNameException();
        }

        if (age < 18) {
            throw new IllegalAgeException();
        }

        System.out.println("您的个人信息在数据库中保存成功...");
    }
}

4. 异常的处理

  1. 声明异常: 这是一种推卸责任的处理方式, 在方法定义的时候通过throws关键字声明异常, 告诉使用者我们的这个位置可能会出现异常, 这种处理异常的态度是, 如果发生了异常我们就上抛给调用者去解决
  2. 捕获异常: 真正意义上的去处理异常, 通过try-catch的方法进行抓住, 如果其他方法调用这个方法的时候, 如果在方法内部已经抓住了, 那么对于调用者来说是不知道异常发生的
  3. 对于运行时异常来说, 我们没有必要进行强制的处理, JVM会自动的将异常向上抛出(throws处理), 所以我们之前发生空指针异常的时候, JVM得到了异常信息之后就会直接的关掉程序
  4. 对于编译时异常来说, 就需要我们手动的处理, 我们可以选择throws把问题抛给上级, 也可以选择try-catch自己捕获住
  5. 对于异常的处理态度应该是声明跟捕获联合使用
  6. 如何进行选择: 如果异常的发生是需要调用者知道的那我们就进行throws抛出, 否则采用捕获

throws方法的具体语法
在这里插入图片描述
try-catch的基本语法
在这里插入图片描述

上面的逻辑的代码采用处理的方式可以改为下面这样

import java.util.Scanner;

/**
 * 测试的主程序
 *  本次测试中我们的异常机制强行抛给了Main函数来处理, 而Main函数又上抛给虚拟机JVM进行处理, 而JVM的处理机制就是直接断掉测试程序
 */
class ExceptionTest{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入名字 : ");
        String name = sc.next();
        System.out.println("请输入年龄 : ");
        int age = sc.nextInt();
        UserService userService = new UserService();
        try{
            userService.register(name,age);
        }catch(IllegalAgeException e) {
            e.printStackTrace();
        }catch(IllegalNameException e){
            e.printStackTrace();
        }
    }
}

5. 异常的使用

我们比较常用的其实就下面的两种方法

  1. getMessage()
    获取到最初创建异常的时候的传递出去的message(也就是那个字符串)
    其实我们分析源码就可以了解到, 当时我们调用super(message)的时候, 我们的message其实给到了throwable中的一个属性字符串, 现在我们调用getMessage()的时候实质上是返回了该字符串
  2. printStackTrace();
    打印的是异常在堆栈中的信息(也就是我们的红色字体), 该方法返回的时候是符合栈的数据结构的, 所以我们查看异常的时候应该从顶部查看(栈顶)

6. finally语句块

  1. finally语句块的代码是一定会执行的
  2. finally语句块不可以进行单独的使用, 一定要配合try块一起使用
    通常的使用结构是 try - finally / try - catch - finally
  3. finally语句块通常完成资源的释放(因为一定会执行)

思考下面的案例的执行结果

public static int m1(){
	try{
		System.out.println("try语句块");
		return 1;
	}finally{
		System.out.println("finally语句块");
	}
}

答案是
 try语句块
 finally语句块
public static int m1(){
	try{
		System.out.println("try语句块");
		System.exit(0);
	}finally{
		System.out.println("finally语句块");
	}
}

答案是
 try语句块

也就是说只有System.exit(0)方法(终止JVM的运行)才能停掉finally语句块的运行

7. 方法覆盖与异常

就一句话, 抛出的异常不可以变多可以变少
如果子类抛出了一个父类抛出异常的父类, 那么这种情况也会编译报错

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【CG】计算机图形学(Computer Graphics)基础(其壹)

0 学习视频 B站GAMES101-现代计算机图形学入门-闫令琪 1 什么是计算机图形学 1.1 什么是好的画面&#xff1f; 画面足够亮。如果全局光照做的好&#xff0c;整个画面就会亮&#xff0c;看起来很舒服。 1.2 计算机图形学涉及到的领域 数学&#xff08;透视&#xff09;投影…

java基础:面向对象(一)

一、概念 物以类聚&#xff0c;分类的思维模式&#xff0c;思考问题首先会解决问题需要哪些分类&#xff0c;然后对这些分类进行单独思考。最后&#xff0c;才对某个分类下的细节进行面向过程的思索。面向对象适合处理复杂的问题&#xff0c;适合处理需要多人协作的问题!对于描…

vulhub靶场之DEVGURU:1

1 信息收集 1.1 主机发现 arp-scan -l 发现主机IP地址为“192.168.1.11 1.2 端口发现 nmap -sS -sV -A -T5 -p- 192.168.1.11 发现端口为&#xff1a;22&#xff0c;80&#xff0c;8585 1.3 目录扫描 dirsearch -u 192.168.1.11 发现存在git泄露 2 文件和端口访问 2…

idea中没有显示‘‘Spring‘‘一栏 (已解决)

第一步: 随便找一个Bean(即直接或者间接使用Component的类) 第二步: 找到左边的图标, 右键这个图标, 然后选择如下选项: 第三步: 成功 然后就成功了, 可以看到具体的bean了以及其bean的关系图等.

MySQL的Geometry数据处理之WKB方案

MySQL的Geometry数据处理之WKT方案&#xff1a;https://blog.csdn.net/qq_42402854/article/details/140134357 MySQL的Geometry数据处理之WKT方案中&#xff0c;介绍WTK方案的优点&#xff0c;也感受到它的繁琐和缺陷。比如&#xff1a; 需要借助 ST_GeomFromText和 ST_AsTex…

主从复制原理及操作

主从复制的概念 主从复制是一种在数据库系统中常用的数据备份和读取扩展技术&#xff0c;通过将一个数据库服务器&#xff08;主服务器&#xff09;上的数据变更自动同步到一个或多个数据库服务器&#xff08;从服务器&#xff09;上&#xff0c;以此来实现数据的冗余备份、读…

数据库之SQL(二)

目录 一、简述SQL中如何将“行”转换为“列” 二、简述SQL注入 三、如何将一张表的部分数据更新到另一张表 四、WHERE和HAVING的区别 一、简述SQL中如何将“行”转换为“列” 我们以MySQL数据库为例&#xff0c;来说明行转列的实现方式。 首先&#xff0c;假设我们有一张分…

WAIC 2024:科技界的摇滚狂欢,你错过了什么?

大数据产业创新服务媒体 ——聚焦数据 改变商业 2024年7月5日&#xff0c;WAIC 2024举办的第二天。数据猿作为受邀媒体&#xff0c;在今天继续亲历这一场关于未来的盛会。在这片汇聚了全球顶尖科技力量的舞台上&#xff0c;见证了人工智能领域的最新成果&#xff0c;感受到了科…

Midjourney对图片细微调整和下载保存

点击v2是对第二图片细微调整。 点击u3对第3张图片进行放大。 保存图片: 对点击u3放大的图片&#xff0c;双击 , 右键保存图片

hdu物联网硬件实验3 按键和中断

学院 班级 学号 姓名 日期 成绩 实验题目 按键和中断 实验目的 实现闪灯功能转换 硬件原理 无 关键代码及注释 /* Button Turns on and off a light emitting diode(LED) connected to digital pin 13, when pressing a pushbutton attached…

招聘一个1-3年经验的Java工程师:企业视角的技能与素质要求

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

Spring的核心基础:感受一下对象工厂

“欢迎来到Spring&#xff01;”的小项目 &#xff08;1&#xff09;写一个HelloSpring的类&#xff0c;采用setter方法注入userName&#xff0c;写一个简单的show方法。 package com.itzhoutao; public class HelloSpring{private String userName;public void setUserName…

Spring源码十一:事件驱动

上一篇Spring源码十&#xff1a;BeanPostProcess中&#xff0c;我们介绍了BeanPostProcessor是Spring框架提供的一个强大工具&#xff0c;它允许我们开发者在Bean的生命周期中的特定点进行自定义操作。通过实现BeanPostProcessor接口&#xff0c;开发者可以插入自己的逻辑&…

核心实验:基于Web前端的性能测试分析!

实验简介 本实验主要利用IE和Chrome的F12开发人员工具结合Web前端测试分析相关知识&#xff0c;对常见网站进行基于前端的性能测试分析&#xff0c;本实验将不会使用到测试开发相关技术&#xff0c;而是纯粹意义上的手工测试&#xff0c;但却是很容易找到系统前端性能及设计问…

AI行业的非零和博弈:解读Mustafa Suleyman的观点

引言 在人工智能&#xff08;AI&#xff09;领域&#xff0c;微软AI公司的CEO Mustafa Suleyman最近在阿斯彭思想节上的访谈引起了广泛关注。与CNBC记者Andrew Ross Sorkin的对话中&#xff0c;Suleyman不仅分享了他对OpenAI人事变动的看法&#xff0c;还深入探讨了AI行业的现…

2024年亚太中文赛数学建模竞赛B题 洪水灾害的数据分析与预测详细思路解析

2024年亚太中文赛数学建模竞赛B题 洪水灾害的数据分析与预测详细思路解析 解题方法&#xff1a; 首先就是对数据进行数据的预处理包括缺失值和异常值处理&#xff0c;之后就是分析哪些指标与洪水的发生有着密切的关联&#xff0c;可以使用相关性分析&#xff08;建议使用斯皮尔…

InetAddress.getLocalHost().getHostAddress()阻塞导致整个微服务崩溃

InetAddress.getLocalHost().getHostAddress()阻塞导致整个微服务崩溃 import java.net.InetAddress;public class GetHostIp {public static void main(String[] args) {try {long start System.currentTimeMillis();String ipAddress InetAddress.getLocalHost().getHostA…

Python和MATLAB微机电健康推导算法和系统模拟优化设计

&#x1f3af;要点 &#x1f3af;惯性测量身体活动特征推导健康状态算法 | &#x1f3af;卷积网络算法学习惯性测量数据估计六自由度姿态 | &#x1f3af;全球导航卫星系统模拟&#xff0c;及惯性测量动态测斜仪算法、动态倾斜算法、融合算法 | &#x1f3af;微机电系统加速度…

Docker搭建MySQL双主复制详细教程

在此之前需要提前安装好Docker和 Docker Compose 。 一、创建目录 首先创建一个本地数据挂载目录。 mkdir -p master1-data master2-data二、编写docker-compose.yml version: 3.7services:mysql-master1:image: mysql:5.7.36container_name: mysql-master1environment:MYSQL_…

解决分布式环境下session共享问题

在分布式环境下&#xff0c;session会存在两个问题 第一个问题:不同域名下&#xff0c;浏览器存储的jsessionid是没有存储的。比如登录时认证服务auth.gulimall.com存储了session&#xff0c;但是搜索服务search.gulimall.com是没有这个session的&#xff1b; 第二个问题&…