Java异常机制

1.异常概述和异常处理机制

异常(exception)概述

异常就是程序在运行时出现的意外的,不正常的情况。

若异常产生后没有正确的处理,会导致程序的中,程序不继续执行,以致造成损失。

2.2 异常处理机制

所以我们在开发中要一套机制来处理各种可能会发生的异常,并对其作出正确的处理,确保程序的 正常执行。这种机制称为异常处理机制java语言是最先提供异常处理机制的。

异常处理机制可以引导程序向正确的方向运行,不至于崩溃。

3 异常处理

java异常处理包含两种代码块。 一种是try...catch,一种是try...catch...finally.

3.1 try...catch

把有可能产生异常的代码放到try中,如果产生异常由catch代码块处理。语法

try{

// 可能产生异常的代码块

} catch(异常类型 ex){

// 异常处理

}

// 后面如果还有代码,无论try中的代码有没有异常,这里都会继续执行

try...catch执行有三种情况 :

情况1:没有发生异常,正常执行

情况2:出现异常, catch代码块捕获异常,并进行异常处理。处理完成后程序继续执行。

需求1 : 从控制台输入两个数并做除法

import java.util.Scanner;

public class TryCatchDemo {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

System.out.println("请输入第一个操作数:");

try{

int num1 = sc.nextInt();

System.out.println("请输入第二个操作数:");

int num2 = sc.nextInt();

int r = num1 / num2;

System.out.println("r = " + r);

}catch (Exception e){

// 负责处理异常

System.out.println("出现输入不匹配异常,然后处理");

}

System.out.println("程序结束");

}

}

异常发生后,从异常发生的那句代码开始,程序不继续向下运行,立即转入异常处理。

情况3:异常不匹配

import java.util.InputMismatchException;

import java.util.Scanner;

public class Test01 {

public static void main(String[] args) {

// 需求:从控制台输入两个数并做除法

Scanner sc = new Scanner(System.in);

System.out.println("请输入第一个操作数:");

try{

int num1 = sc.nextInt();

System.out.println("请输入第二个操作数:");

int num2 = sc.nextInt();

int r = num1 / num2;

System.out.println("r = " + r);

}catch (InputMismatchException e){

// 负责处理异常

System.out.println("出现输入不匹配异常,然后处理");

}

System.out.println("程序结束");

}

}

异常不匹配,程序中断,此时我们就需要多重catch了。

3.2 多重catch

可以为try代码书写多个catch用于捕获多个具体的异常。

书写时 : 子类在上,父类在下。

import java.util.InputMismatchException;

import java.util.Scanner;

public class MutiCatchDemo {

public static void main(String[] args) {

System.out.println("begin");

divide("17", "0");

System.out.println("ending");

}

public static void divide(String a, String b) {

try {

int x = Integer.parseInt(a);

int y = Integer.parseInt(b);

System.out.println(x / y);

} catch (NumberFormatException e) {

//处理数字格式化异常的代码

System.out.println("字符串不包含可解析的整数");

} catch (ArithmeticException e) {

//处理算术异常的代码

System.out.println("除数不能为0");

} catch (Exception e) {

//处理其他未知的异常

System.out.println("未知异常");

}

}

}

3.3 异常对象

异常对象是出现异常时的那条语句产生的(jvm 自动创建)

异常在java类中通过Exception或其具体子类创建,大多数情况下都是由其子类(命名方式:常类型 +Exception)创建, Exception是所有异常类的父类

常用方法

方法介绍

toString

返回异常类型和异常信息

getMessage

返回异常信息

printStackTrace

打印堆栈信息(红色)。包含了异常信息,异常类型,异常位置,方便程序开发 阶段的调试(一般要打开),也是JVM默认的异常处理机制

java.util.InputMismatchException

        at java.util.Scanner.throwFor(Scanner.java:864)

        at java.util.Scanner.next(Scanner.java:1485)

        at java.util.Scanner.nextInt(Scanner.java:2117)

        at java.util.Scanner.nextInt(Scanner.java:2076)

        at com.kal02.exception02.Test02.main(Test02.java:14)

异常堆栈信息:

第一句:表示异常类型和异常的Message构成

最后一句:包含具体发生异常的全路径类,方法,产生异常语句的行数。

com.kal02.exception02.Test02.main(Test02.java:14)

3.4 try...catch...finally

try...catch 和之前一样用于捕获并处理异常, finally代码块用于处理异常后的收尾工作。

不管是否发生异常, finally总执行。

finally的收尾工作包含释放内存、关闭文件、关闭网络连接、关闭数据库、关闭...

step 1: 打开文件

step 2: 操作文件

step 3: 关闭文件

存在returntry...catch...finally

public class TryCatchFinallyDemo {

public static int div(int a,int b) {

int r = 0;

try {

r = a / b;

return r;

} catch (Exception e) {

System.out.println(e.toString());

} finally {

System.out.println("我是finally");

}

return r;

}

public static void main(String[] args) {

System.out.println(div(10,0));;

System.out.println("程序正常结束!");

}

}

总结:

.  存在returntry...catch...finally块,finally先执行,然后执行return  return 是最后执行的。

添加try-catch快捷键

IDEA : Ctrl + Alt + T

4 异常分类

4.1 异常的继承体系                                        

Throwable类有两个子类ErrorException,分别表示错误和异常。

Exception Error的子类大都是以ErrorException作为类名后缀。

4.1.1 Error

Error,表示代码运行时 JVMJava 虚拟机)出现的问题。如系统崩溃或内存溢出等,不需要处理 Error

常见的Error

  StackoverflowError:当应用程序递归太深而发生堆栈溢出时,抛出该错误。比如死循环或者没有 出口的递归调用。

 outofMemoryError:因为内存溢出或没有可用的内存提供给垃圾回收器时,  Java 虚拟机无法分配 一个对象,这时抛出该错误。比如new了非常庞大数量的对象而没释放。

1.4.2 Exception

Exception,表示程序在运行时出现的一些不正常情况, 般大多数表示轻度到中度的问题,属于    可预测、可恢复问题。如除数为0,数组索引越界等,这种情况下,程序员通过合理的异常处理,确保程 序的正常运行直到结束,常见的Exception

  

ArrayIndexoutofBoundsException:用非法索引访问数组时抛出的异常。如果索引为负或大于等 于数组大小,则该索引为非法索引。

  ArithmeticException:当出现异常的运算条件时,抛出此异常。例如,  一个整数除以零时,抛出 此类的一个实例。

.  NullPointerException:当应用程序试图在需要对象的地方使用 null 时,抛出该异常。这种情况包 括:

异常体系分成: checked (编译)异常和runtime(运行)异常。

划分规则是, RuntimeException和其子类属于运行时异常,异常除了运行时异常,其他都是编译时异 常。

4.2 异常分类                                                                                    

4.2.1 运行时异常                                                                                      

runtime异常,顾名思义在编译时期不被检测,只有在运行时期才会被检查出来。

运行异常可以不使用try...catch处理,但一旦出现异常就将由JVM处理(打印堆栈信息)。

RuntimeException  (运行时异常)通常是指因设计或实现方式不当而导致的问题。程序员小心谨慎是可 以避免的异常。如:事先判断对象是否为null就可以避免NullPointerException异常,事先检查除数不为 0就可以避免ArithmeticException异常。

运行时异常特点:

在编译阶段,Java编译器检查不出来。 一般的,程序可以不用使用try-catchthrows处理运行异常。

简而言之: 对于运行时异常程序可处理(使用try-catchthrows处理),可不处理

4.2.2 编译时异常                                                                                                

编译时异常,顾名思义就是在编译时期就会被检测到的异常。除了RuntimeException以及子类以 外,其他的Exception及其子类都是编译异常,有时候也称之为检查时异常

编译时异常特点:

在编译阶段,Java编译器会检查出异常,也就说程序中一旦出现这类异常,要么使用try-catch语句 捕获,要么使用throws语句声明抛出它,否则编译就不会通过。

简而言之: 程序要求必须处理编译异常,使用try-catchthrows处理

常见面试题:请罗列常见的运行时异常和编译时异常(3-5个)

编译时异常(检查时异常) :程序必须做出处理, 一般继承于Exception

运行时异常:程序可处理,也可不处理。都继承于RuntimeException

意识:遇到不懂的异常类时,首先要分辨它属于检查时还是运行时异常。通过快捷键(ctrl+h)查看

5 声明异常

5.1 throws

Java语言中通过throws声明某个方法可能抛出的各种异常。

当方法的定义者在定义方法时知道调用该方法时可能出现异常,定义者又不知道如何处理时,此时方法 定义者可以选择声明异常,使用throws关键字,可以声明多个异常,用( , )号分隔。形式:

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

}

需求1:声明异常

public class Test01Throws {

// divide方法可能有异常,但divide处理不了该异常,就通过throws声明异常,让divide方法的调 用者来处理

public static void divide(int a, int b) throws Exception {

System.out.println(a / b);

}

public static void main(String[] args) {

try {

divide(3, 1);

divide(1, 0);// 调用divide方法,调用者必须处理或再次抛出

} catch (Exception e) {

e.printStackTrace();

}

}

}

声明异常的原因:该方法自身处理不了该异常,只能使用throws提醒该方法的调用者需要处理异常。当

然调用者也有两种处理方式:  自己捕获处理或再次声明(要么try...catch ,要么也throws)。

需求2:异常继续上抛

public class Test01Throws {

public static void main(String[] args) throws Exception{

// 调用divide方法,调用者必须处理或再次抛出

divide(1, 0);

}

//divide方法可能有异常,但divide处理不了该异常,就抛出,让divide方法的调用者来处理

public static void divide(int a, int b) throws Exception {

System.out.println(a / b);

}

}

在异常声明或者上抛出的过程中,应该遵循以下原则:能在调用处明确处理优先处理,否则继续上抛。

声明异常时要根据异常的分类来确定是否外界(调用处)是否必须处理该方法产生的异常。如果需要外界必 须处理,需要声明检查时异常,否则声明运行时异常。

6 手动抛出异常 throw

在实际开发过程中,开发者也可以根据程序的需要,手动抛出异常,通过throw关键字。语法

XxException ex = new XxException();

throw ex;

或者

throw new XxException();

当程序出现某种逻辑问题时由程序员主动抛出某种特定类型的异常。

public class ThrowDemo {

public static void main(String[] args) {

try {

ThrowDemo.isExist("will");

} catch (Exception e) {

System.out.println(e.getMessage());//对不起,用户名will已经存在 }

}

public static boolean isExist(String userName) throws Exception {

String[] data = { "will", "lucy", "lily" }; // 模拟已经注册的用户名 if (userName != null && userName.length() > 0) {

for (String name : data) {

if (name.equals(userName)) {// 用户名相同,证明该用户已经存在 // 手动抛出一个异常表示存在的不正常情况

throw new Exception("对不起,用户名" + userName + "已经存在"); }

}

}

return false;

}

}

7 自定义异常

JDK 中的异常类型不能满足程序的需要时(也即需要定义具体的业务异常时),可以自定义异常。

自定义异常的步骤

[1] 确定异常类型(编译时异常、运行时异常)。

[2] 继承异常的父类(编译时异常Exception、运行时异常RuntimeException)

[3] 声明构造方法

public class Student {
private String name;
private int age;public Student(String name, int age) {
this.name = name;
this.setAge(age);
}public Student() { }public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public int getAge() {
return age;
}public void setAge(int age) throws AgeException{
if( age < 0 || age > 120 ) {
// System.out.println("年龄值不合法");
// 能否手动抛出一个年龄异常呢?
AgeException ex = new AgeException("年龄值不能小于0或者不能大于120"); throw ex;
} else {
this.age = age;
}
}
}

测试

public class CustomExceptionDemo {

public static void main(String[] args) {

Student s1 = new Student("二狗",20);

try {

s1.setAge(130);

} catch (AgeException e) {

// System.out.println(e.toString());

System.out.println(e.getMessage());

}

}

}

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

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

相关文章

计算机网络 —— 网络层(子网掩码和子网划分)

计算机网络 —— 网络层&#xff08;子网掩码和子网划分&#xff09; 网络地址转换NAT子网掩码和子网划分举个例子第一步&#xff1a;看类型第二步&#xff1a;从主机号开始比对第三步&#xff1a;去头去尾 我们今天来看子网掩码和子网划分&#xff1a; 网络地址转换NAT 网络…

用于认知负荷评估的集成时空深度聚类(ISTDC)

Integrated Spatio-Temporal Deep Clustering (ISTDC) for cognitive workload assessment 摘要&#xff1a; 本文提出了一种新型的集成时空深度聚类&#xff08;ISTDC&#xff09;模型&#xff0c;用于评估认知负荷。该模型首先利用深度表示学习&#xff08;DRL&#xff09;…

人工智能在【肿瘤生物标志物】领域的最新研究进展|顶刊速递·24-06-08

小罗碎碎念 本期文献速递的主题是——人工智能在“肿瘤生物标志物”领域的最新研究进展。 重点关注 今天推荐的6篇文献中&#xff0c;第二篇和第三篇是小罗最喜欢的&#xff0c;因为对于临床来说&#xff0c;比较具有实际意义&#xff0c;也和自己的想法很契合。 尤其是第三篇…

每日一题——Python实现PAT甲级1015 Reversible Primes(举一反三+思想解读+逐步优化)

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 is_prime函数分析&#xff1a; decimal_to_base函数分析&#xff1a; 主循…

Shell脚本学习_环境变量深入

目录 1.Shell环境变量深入&#xff1a;自定义系统环境变量 2.Shell环境变量深入&#xff1a;加载流程原理介绍 3.Shell环境变量深入&#xff1a;加载流程测试 4.Shell环境变量深入&#xff1a;识别与切换Shell环境类型 1.Shell环境变量深入&#xff1a;自定义系统环境变量 …

旧衣回收小程序开发,轻松回收旧衣物

随着环保理念的增强&#xff0c;回收市场得到了快速发展&#xff0c;吸引了不少年轻人进入到市场中创业。除了传统的废品回收外&#xff0c;旧衣回收也受到了大众的重视&#xff0c;市场规模迅速扩大&#xff0c;大众浪费的衣物也获得了归处。 目前旧衣回收的方式主要是线上与…

makefile与进度条

Linux项目自动化构建工具-make/makefile make是一个命令&#xff0c; makefile是一个文件&#xff0c;保存依赖关系和依赖方法。‘ touch Makefile/makefile mybin:mytest.c//依赖关系 目标文件&#xff1a;依赖文件列表 文件列表的文件之间以空格分隔 gcc -o mybin mytest.…

Shell脚本学习_字符串变量

目录 1.Shell字符串变量&#xff1a;格式介绍 2.Shell字符串变量&#xff1a;拼接 3.Shell字符串变量&#xff1a;字符串截取 4.Shell索引数组变量&#xff1a;定义-获取-拼接-删除 1.Shell字符串变量&#xff1a;格式介绍 1、目标&#xff1a; 能够使用字符串的三种方式 …

linux系统——ping命令

ping命令可以用来判断对远端ip的连通性&#xff0c;可以加域名也可以加公共ip地址 这里发送出56字节&#xff0c;返回64字节

ctfshow-web入门-命令执行(web41_exp与分析)

过滤不严&#xff0c;命令执行 preg_match(/[0-9]|[a-z]|\^|\|\~|\$|\[|\]|\{|\}|\&|\-/i, $c) 过滤掉了数字、字母以及一些符号&#xff0c;之前接触过的无字母 rce 是取反编码再取反&#xff0c;采用不可见字符去绕过正则&#xff0c;但是这里取反符号被过滤掉了&#x…

Kali linux学习入门

Kali linux学习入门 文章目录 Kali linux学习入门Kali Linux简介Kali Linux工具篇Kali Docker安装Docker 更换国内镜像源Kali 安装 docker compose Kali Linux文档篇Kali Linux 社区篇 Kali Linux简介 Kali Linux是专门用于渗透测试linux操作系统&#xff0c;它由BackTrack发展…

软件游戏找不到d3dx9_43.dll怎么办,三分钟教你解决此问题

在现代科技发展的时代&#xff0c;电脑已经成为我们生活中不可或缺的一部分。然而&#xff0c;在使用电脑的过程中&#xff0c;我们可能会遇到一些问题&#xff0c;其中之一就是电脑缺失d3dx943.dll文件。这个问题可能会影响到我们的正常使用&#xff0c;因此了解其原因和解决方…

接口(API)开发,测试工具-apifox

前言 为什么需要接口&#xff08;API&#xff09;? 因为不同的平台或系统可能使用不同的技术栈、编程语言或数据格式。API提供了一个标准化的方式&#xff0c;使得这些不同的系统可以相互交换数据和功能调用&#xff0c;实现互操作性 在开发日常的项目交互中&#xff0c;不…

PyCharm中 Fitten Code插件的使用说明一

一. 简介 Fitten Code插件是是一款由非十大模型驱动的 AI 编程助手&#xff0c;它可以自动生成代码&#xff0c;提升开发效率&#xff0c;帮您调试 Bug&#xff0c;节省您的时间&#xff0c;另外还可以对话聊天&#xff0c;解决您编程碰到的问题。 前一篇文章学习了 PyCharm…

小白教程--- kali(po解)WIFI密码 (图文教程)

kali学得好&#xff0c;牢饭少不了&#xff01;&#xff01;&#xff01; 原理&#xff1a; 模拟WiFi的已连接设备&#xff0c;强制让其下线重连&#xff0c;获取其握手包&#xff0c;使用密码字典&#xff08;宝丽&#xff09;婆洁。 环境&#xff08;准备工作&#xff09;&a…

深度解析:ChatGPT全面测评——功能、性能与用户体验全景剖析

从去年底至今&#xff0c;由 OpenAI 发布的大规模语言模型 ChatGPT 引发了几乎所有科技领域从业者的高度关注。据瑞银集团的报告显示&#xff0c;自 2023 年 1 月起&#xff0c;仅两个月内&#xff0c;ChatGPT 的月活用户数便超过了 1 亿。 ChatGPT 被誉为“最强 AI”&#xff…

操作系统总结

进程和线程的区别 本质区别&#xff1a; 进程是资源调度以及分配的基本单位。线程是 CPU 调度的基本单位。 所属关系&#xff1a;一个线程属于一个进程&#xff0c;一个进程可以拥有多个线程。地址空间&#xff1a; 进程有独立的虚拟地址空间。线程没有独立的虚拟地址空间&…

Day53 动态规划part12

LC309买卖股票的最佳时机含冷冻期 与LC122类似&#xff0c;都是可无限次购买股票&#xff0c;只不过引入了冷冻期的概念dp[i][0] 第i天持有股票收益&#xff1b;dp[i][1] 第i天不持有股票收益;情况一&#xff1a;第i天是冷静期&#xff0c;不能以dp[i-1][1]购买股票,所以以dp[…

性能测试 —— Jmeter对数据库压力测试

Jmeter先要和数据库建立连接&#xff0c;sql语句是在Jmeter中写的&#xff0c;但是语句的执行是在数据库里执行的&#xff0c;数据库再将执行结果返回给Jmeter。 在做jmeter数据库压力测试之前&#xff0c;要先检查是否有mysql-connector-java-5.1.39-bin.jar的这个包&#xf…

flink读取hive写入http接口

目录 0、创建hive数据 1、pom.xml 2、flink代码 3、sink 4、提交任务jar 5、flink-conf.yaml 6、数据接收 flink-1.17.2jdk1.8hive-3.1.3hadoop3.3.6passwordhttp0、创建hive数据 /cluster/hive/bin/beeline !connect jdbc:hive2://ip:10000 create database demo; d…