零基础Java第二十一期:异常(一)

embedded/2024/11/28 4:34:43/

目录

一、异常的概念与体系

1.1. 异常的概念

 1.2. 异常的体系结构

1.3.  异常的分类

二、异常的处理 

2.1.  防御式编程

2.2. 异常的抛出

2.3. 异常的捕获


一、异常的概念与体系

1.1. 异常的概念

       在Java中,将程序执行过程中发生的不正常行为称为异常。异常是Java语法中的核心环节,是一种针对程序的错误处理的科学方式。

       在C语言,是没有异常的机制的,因为C语言比较“古老”了;在C++中,引入了异常,但只是一个“半成品”;而Java的异常是比较完善的体系。

       这里我们要注意异常与编译出错的差别。还有几种常见的异常,如数组的越界访问,空指针异常。

java">System.out.printl("hello");//编译出错
System.out.println(10 / 0);//异常,运行时出错,会抛出异常

java">int[] array1 = {1,2,3};
System.out.println(array1[10]);//数组的越界访问int[] array2 = null;
System.out.println(array2.length);//空指针

 1.2. 异常的体系结构

 

       从上图中我们可以看到,Throwable是异常体系的顶层类,其派生出两个重要的子类, Error 和 Exception。Error是在JVM内部使用的, 程序员一般用不到Error。我们需要重点学习的是Exception。这么多类我们不需要背,因为Java标准库提供了很多现成的异常。

1.3.  异常的分类

(1)受查异常,在程序编译期间发生的异常,这样的异常必须要显式处理。

java">public class Person {private String name;private String gender;int age;@Overrideprotected Person clone() {return(Person) super.clone();}
}public class Main {public static void main(String[] args) {Person one = new Person();System.out.println();}
}

      上面的代码会在出现异常的位置下出现红色的波浪线,来提示我们出现了异常。受查异常不处理,代码就无法通过编译。

java">import java.io.FileNotFoundException;public class Main {//throws后面可以接可能抛出的异常private static void openConfig(String filename) throws FileNotFoundException{if(!filename.equals("config.txt")){throw new FileNotFoundException("文件不存在");}}public static void main(String[] args) throws FileNotFoundException {openConfig("xxx");}
}

(2) 非受查异常

      在程序执行期间发生的异常,RunTimeException以及其子类对应的异常,都称为非受查异常。

二、异常的处理 

       在Java中,异常处理主要的5个关键字:throw、try、catch、final、throws。 

2.1.  防御式编程

(1) LBYL:Look Before You Leap。在操作之前就做充分的检查。即:事前防御型。缺陷:正常流程和错误处理流程代码混在一起, 代码整体显的比较混乱。

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

 (2)EAFP: It's Easier to Ask Forgiveness than Permission。“事后获取原谅比事前获取许可更容易"。也就是先操作,遇到问题再处理。即:事后认错型

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

        优势:正常流程和错误流程是分离开的, 程序员更关注正常流程,代码更清晰,容易理解代码 异常处理的核心思想就是 EAFP。

2.2. 异常的抛出

       在编写程序时,如果程序中出现错误,此时就需要将错误的信息告知给调用者。在Java中,可以借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者。 

语法规则:

java">throw new xxxException(“产生异常的原因”)
java">//在数组中查找一个元素public class Main {public static int getElment(int[] array,int index){if(array == null){// 数组为空, 抛出空指针异常throw new NullPointerException("传递的数组为null");}if(index<0 || index>= array.length){// 数组下标越界, 抛出另一个异常throw new ArrayIndexOutOfBoundsException("数组越界异常");}return array[index];}public static void main(String[] args) {int[] arrs = {1,2,3};getElment(arrs,3);}
}

     这样我们就能看到抛出的异常并给了一个提示,正是我们在异常当中所传递的参数。

注意:throw必须写在方法体内部;抛出的对象必须是Exception 或者 Exception 的子类对象; 异常一旦抛出,其后的代码就不会执行

2.3. 异常的捕获

(1)throws关键字 

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

语法规则: 

java">修饰符  返回值类型   方法名(参数列表) throws 异常类型1,异常类型2...{
}
java">import java.io.FileNotFoundException;public class Main {//throws加在方法后面,声明这个方法可能抛出的异常private static void openConfig(String filename) throws FileNotFoundException{if(!filename.equals("config.txt")){throw new FileNotFoundException("文件不存在");}}public static void main(String[] args) throws FileNotFoundException {openConfig("xxx");}
}

       注意:声明的异常必须是 Exception 或者 Exception 的子类;方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型 具有父子关系,直接声明父类即可;调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出。

       throw与throws的区别:throw是真得抛出来一个异常对象,而throws只是声明了一下,真正抛没抛,不知道。

(2)try-catch捕获并处理

       throws只是声明,声明告诉方法的调用者来处理异常。真正进行异常处理,要通过try-catch。 

语法规则: 

java">try{// 将可能出现异常的代码放在这里
}catch(要捕获的异常类型  e){// 如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常类型一致时,或者是try中抛出异常的基类
时,就会被捕获到// 对异常就可以正常处理,处理完成后,跳出try-catch结构,继续执行后序代码
java">import java.io.FileNotFoundException;
import java.io.IOException;public class Main {public static void openConfig(String filename) throws IOException{if(!filename.equals("config.txt")){throw new FileNotFoundException("文件不存在");}}public static void main(String[] args) {try {openConfig("xxx");System.out.println("调用完成");} catch (IOException e) {//e是IOException的一个对象,这个对象是由throw抛出的System.out.println("进入到异常处理逻辑中");}}
}

        我们在调用openConfig后面加上一条语句,这是因为openConfig发现了异常,意味着这个代码块不会再执行后面了,直接进入后面的catch语句。

        这里还有一个小技巧,我们把鼠标光标放在被调用的方法上,然后alt加回车,直接出现要抛出的异常,很快就能生成。 

 

       catch 语句中, 一般会打印出异常的详细信息,printStackTrace() 方法可以打印异常的详细信息,主要就是调用栈。

       调用栈就会抛出异常的位置是怎样一层一层调过去的。 

       catch语句可以有多个具体catch哪些异常,取决于try抛出哪些异常。 

java">import java.io.FileNotFoundException;
import java.io.IOException;public class Main {public static void openConfig(String filename) throws IOException {if(!filename.equals("config.txt")){throw new FileNotFoundException("文件不存在");}}public static int getElment(int[] array,int index){if(array == null){// 数组为空, 抛出空指针异常throw new NullPointerException("传递的数组为null");}if(index<0 || index>= array.length){// 数组下标越界, 抛出另一个异常throw new ArrayIndexOutOfBoundsException("数组越界异常");}return array[index];}public static void main(String[] args) {try {String str = null;str.length();openConfig("xxx");System.out.println("调用完成");} catch (IOException e) {System.out.println("进入到异常处理逻辑中");e.printStackTrace();} catch (NullPointerException e){System.out.println("空指针异常");e.printStackTrace();}}
}

        catch里面每一个独立的代码块,里面的e都是代码块里面的局部变量,所以不用担心e的命名不同。


http://www.ppmy.cn/embedded/141094.html

相关文章

详解八大排序(一)------(插入排序,选择排序,冒泡排序,希尔排序)

文章目录 前言1.插入排序&#xff08;InsertSort&#xff09;1.1 核心思路1.2 实现代码 2.选择排序&#xff08;SelectSort&#xff09;2.1 核心思路2.2 实现代码 3.冒泡排序&#xff08;BubbleSort&#xff09;3.1 核心思路3.2 实现代码 4.希尔排序&#xff08;ShellSort&…

uni-app 蓝牙开发

一. 前言 Uni-App 是一个使用 Vue.js 开发&#xff08;所有&#xff09;前端应用的框架&#xff0c;能够编译到 iOS、Android、快应用以及各种小程序等多个平台。因此&#xff0c;如果你需要快速开发一款跨平台的应用&#xff0c;比如在 H5、小程序、iOS、Android 等多个平台上…

Day 27 贪心算法 part01

贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。 不用花心思去研究其规律, 没有思路就立刻看题解。 基本贪心的题目 有两个极端,要不就是特简单,要不就是死活想不出来。 学完贪心之后再去看动态规划,就会了解贪心和动规的区别。…

CTF之密码学(密码特征分析)

一.MD5,sha1,HMAC,NTLM 1.MD5:MD5一般由32/16位的数字(0-9)和字母(a-f)组成的字符串 2.sha1:这种加密的密文特征跟MD5差不多,只不过位数是40(sha256:64位;sha512:128位) 3.HMAC:这种算法就是在前两种加密的基础上引入了秘钥,而秘钥又只有传输双方才知道,所以基本上…

企业OA管理系统:Spring Boot技术深度解析

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

C#中面试的常见问题001

1、c#访问修饰符有哪些 public&#xff1a;公共访问级别&#xff0c;成员可以被任何其他代码访问。private&#xff1a;私有访问级别&#xff0c;成员只能在定义它的类内部访问。protected&#xff1a;受保护的访问级别&#xff0c;成员可以被定义它的类及其子类访问。interna…

第八章 Spring Boot快速⼊⻔ —— Spring Boot整合thymeleaf模板引擎

前言: Thymeleaf 是一个现代服务器端的 Java 模板引擎,用于Web环境以及非Web环境。它能够处理HTML、XML、JavaScript、CSS甚至纯文本。Thymeleaf的主要目标是提供一种优雅的自然模板方式,而不是像某些模板引擎那样使用特定标签或标记语言。 官方文档: Thymeleaf官方文档h…

占用磁盘100%?Apache DolphinScheduler 日志如何定时清理!

当 Apache DolphinScheduler 运行几个月后&#xff0c;大部分朋友会发现 Logs 下的运行日志越来越多&#xff0c;这时可以考虑清理下 Logs/ 目录下的日志文件&#xff0c;比如设置只保留最近 3 天的日志&#xff0c;怎么操作呢&#xff1f; 可以通过执行以下三个命令来实现&…