12、异常Exception:

12、异常Exception:

我们来看一段代码,了解下为什么需要异常处理:

package com.jiangxian.Exception_;/*** @author JiangXian~* @version 1.0*/
public class Exception01 {public static void main(String[] args) {int num1 = 10;int num2 = 0;int res = num1/num2;System.out.println("程序继续运行...");}
}

好的,这段代码会报错,出错的原因是除数为0了。我们来想一想这样子合不合理,倘若我们有一个很庞大的代码,我们因为这一个非常细微的错误,导致我们代码的崩溃,从而后续的所有代码都不执行了,这样做合理吗?显然是不合理的,这样我们的系统不够健壮

解决方法:异常捕获

对异常进行捕获,保证程序可以继续运行。

package com.jiangxian.Exception_;/*** @author JiangXian~* @version 1.0*/
public class Exception01 {public static void main(String[] args) {int num1 = 10;int num2 = 0;// 1.num1/num2 => 10/0// 2.当执行到 num1/num2 因为 num2 = 0,程序就会出现(抛出)异常,此处为 ArithmeticException// 3.当抛出异常后,程序就崩溃了,下面的代码就不再执行;// 4.当我们认为一段代码可能出现 异常/问题,可以使用 try-catchtry {int res = num1/num2;} catch (Exception e) {e.printStackTrace();}System.out.println("程序继续运行...");// 加入异常处理机制,虽然有异常仍然会执行后面的代码。}
}

异常介绍:

基本概念:

java语言中,将程序执行中发生的不正常情况称为“异常“。(开发过程中的语法错误和逻辑错误不是异常!)

可以分为两大类:

  1. Error(错误):java虚拟机无法解决的严重问题。如JVM系统内部错误,资源耗尽等严重情况。
  2. Exception:因编译错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。其还能继续细分。
    1. 运行时异常(RUNTIME),在程序运行时会发生的异常;
    2. 编译时异常,编译器检查出的异常。

异常体系图:

  1. 异常分为两大类,运行时异常和编译时异常;
  2. 运行时异常,编译器检查不出来。一般指编程时的逻辑错误,==程序员应该尽力去避免其出现(否则整个代码中全是try-catch语句)。对于运行时异常,可以不做异常处理,报错了去更改即可,否则这种异常过于普遍,导致程序的可读性大大降低;
  3. 编译时异常,是编译器要求必须处理的异常。

常见的运行时异常:

  1. NullPointException——空指针异常;
  2. ArithmeticException——数学运算异常;
  3. ArrayIndexOutOfBoundsException——数组下标越界异常;
  4. ClassCastException——类型转换异常;
  5. NumberFormatException——数字格式不正确异常。

举例:

NullPointException:

当应用程序在需要对象的地方使用null时,抛出异常。(对象还没有创建出来就使用了)

package com.jiangxian.Exception_;/*** @author JiangXian~* @version 1.0*/
public class NullPointException_ {public static void main(String[] args) {String name = null;System.out.println(name.length());}
}

ArithmeticException:

当出现异常的运算条件时,抛出此异常。例如一个整数除以0。

/*** @author JiangXian~* @version 1.0*/
public class ArithmeticException_ {public static void main(String[] args) {int num1 = 10;int num2 = 0;int res = num1 / num2;}
}

ArrayIndexOutOfBoundsException:

用非法的索引去访问数组时抛出的异常。如索引为负数或大于等于数组的length-1,则该索引为非法索引。

package com.jiangxian.Exception_;/*** @author JiangXian~* @version 1.0*/
public class ArrayIndexOutOfException_ {public static void main(String[] args) {int[] a = new int[5];System.out.println(a[5]);}
}

ClassCastException:

当试图将对象强制转换为不是实例的子类时,抛出该异常。

package com.jiangxian.Exception_;/*** @author JiangXian~* @version 1.0*/
public class ClassCastException {public static void main(String[] args) {A a = new B(); // 向上转型B b = (B)a; // 向下转型,okC c = (C)a; // 不行}
}class A{}
class B extends A{}
class C extends A{}

NumberFormatException:

当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,会抛出异常。

例子就是英文不能作为数字输出。

package com.jiangxian.Exception_;/*** @author JiangXian~* @version 1.0*/
public class NumberFormatException {public static void main(String[] args) {String name = "JiangXian";int num = Integer.parseInt(name);System.out.println(num);}
}

小结一些我的发现:

这些异常,都是会被标注为黄色的Warning,我们可以无视它运行程序(但是程序可能会报错)。

所以运行异常会被标注为黄色的Warning;但是并不是所有的黄色Warning都是运行异常!

其能够通过编译,但是运行不能成功。


编译异常:

编译异常是指在编译期间,就必须处理的异常,否则代码不能通过编译。(你可以去终端中尝试 javac 编译一下,发现,运行异常,是会正常生成字节码文件.class的,但是编译异常是生成不了的,还会报错)。

常见的编译异常:

一般发生在,网络、文件、数据库操作的情况。

  1. SQLException——操作数据库时,查询表可能发生异常;
  2. IOException——操作文件时,发生的异常;
  3. FileNotFoundException——当操作一个不存在的文件时,发生异常;
  4. ClassNotFoundException——加载类,而该类不存在时,异常;
  5. EOFException——操作文件,到文件末尾,发生异常;
  6. IllegalArguementException——参数异常。

异常处理:

基本介绍:

异常处理就是当异常发生时,对异常处理的方式;

异常处理的方式:

  1. try-catch-finally:程序员在代码中捕获发生的异常,自行处理。
  2. throws:将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者就是JVM。

try-catch-finally:

java中提供 trycatch块来处理代码。

catch块——用于处理 try 中发生地异常。

根据需求在程序中可以有多个 try…catch块。

处理机制:

try{代码/可能有异常
}catch(Exception e){// 捕获到异常:// 1.当异常发生时;// 2.系统将异常封装为Exception 对象 e,传递给 catch;// 3.得到异常对象后,程序员,自行处理;// 4.注意若没有异常,catch 代码块不执行代码块
}fianlly{// 1.不管是否有异常发生,始终要执行finally;// 2.所以,通常将释放资源的代码,放在finally中。代码块
}

细节:

  1. 若异常发生了,那么异常发生后面地代码不会执行,直接进入到 catch 块;

  2. 若异常没有发生,则顺序执行 try 代码块,不会进入到 catch;

  3. 若希望不管是否发生异常,都执行某段代码(关闭连连接,释放资源),则使用 finally{}代码块;

  4. 可以有多个catch语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(Exception 在后,NullPointException 在前),若发生异常,指挥匹配一个catch;

    package com.jiangxian.exception_;public class try_catch_detail {public static void main(String[] args) {// 解读:// 1. 若try代码块可能有多个异常// 2.可以用多个catch去捕获不同的异常// 3.要求子类异常在前,父类异常写在后面try{Person person = new Person();person = null;System.out.println(person.getage()); // NullPointExceptionint n1 = 10;int n2 = 0;int res = n1 / n2; // ArithmaticException}catch(NullPointerException e){System.out.println("空指针异常:" + e.getMessage());}catch(ArithmeticException e){System.out.println("算数异常:" + e.getMessage());}catch(Exception e){System.out.println(e.getMessage());}}
    }class Person{int age = 10;public int getage(){return age;}
    }
  5. 可以进行 try-finally 配合使用,这种用法相当于没有捕获异常,因此程序会直接崩掉/退出。应用场景——执行一段代码,不管是否发生异常,都必须执行某个业务逻辑。

    package com.jiangxian.exception_;public class tryCatchDetail {public static void main(String[] args) {try{int n1 = 10;int n2 = 0;int res = n1 / n2;}finally{System.out.println("程序继续运行...");}}
    }
    // 由于没有进行任何的处理,所以实际上时JVM进行的异常处理,在终端会直接报错。
    
  6. 当 catch 和 finally 都有return的时候,若捕获到异常,先执行 catch 中的 return 语句,但暂时不返回,返回的是finally中的 return 语句中的结果(catch 的语句执行但不返回,返回的是 finally 中 的renturn);

  7. 当 finally 无 return,但catch 中有return时,先执行catch 中的return 语句,但暂时不执行,然后执行 finally 中的语句,最后回到catch 的语句执行返回。(如 catch 中是 return i; 但是 finally 中有个++i,那么在第一次遇到return 语句的时候,会有个temp变量暂存i,执行完++i操作后,回到catch 中的return 语句是,将temp 的值重新赋值给i,再返回)。

Exercise:

要求输入字符串,判断是不是整数,不是就一直输入,直到是整数为止。

throws(抛出):

基本介绍:

  1. 若一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表面该方法将不对这些异常进行处理,而是由方法的调用者负责处理

  2. 在方法声明中throws语句可以声明抛出异常的列表(可以抛出多个种类的异常),throws后面地异常类型可以是方法中产生地异常类型,也可以是它的父类。

    package com.jiangxian.exception_.throws_;import java.io.FileInputStream;
    import java.io.FileNotFoundException;public class Throws01 {public static void main(String[] args) {}public void f1() throws FileNotFoundException,NullPointerException/*写成Exception即它的父类也可以*/ {// 创建了一个文件流对象// 这是一个编译时异常,必须处理// 1.可以使用try-catch// 2.使用throws,明确抛出异常,让调用f1方法的调用者处理// 3.throws后也可以是异常列表(也可以用一个Exception代替是所有的)FileInputStream fis = new FileInputStream("d://aa.txt");}
    }

处理机制:

  1. try-catch-finally 和 throws 二选一;
  2. 若程序员,没有显示地处理异常,默认采用throws。

模拟流程:

JVM -》调用 main -》调用 f1 -》调用f2(此处发生异常);

f2(抛出异常)-- throws(当也可以时try-catch)-》f1– throws(也可以try-catch)-》main–throws(try-catch)-》JVM。

throws 实际上就是 当前不想处理,返回给上级,让上级去处理,若都不处理,那么最高级JVM处理异常机制特别暴力,其会输出异常并退出程序。

细节:

  1. 对于编译异常,程序中必须处理,比如 try-catch 或 throws;

  2. 对于运行时异常,程序中若没有处理,默认就是 throws的方法;

    public class ThrowsDetails {public static void main(String[] args) {}public static void f1() /*默认有 throws ArithmeticExpection*/{int n1 = 10;int n2 = 0;int res = n1/n2;}
    }
    
  3. 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类异常的子类;

    class Father{void method() throws RuntimeException{}
    }class Son extends Father{// 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,//      所重写的异常类型需要是父类的异常或是父类异常的子类@Overridepublic void method() throws NullPointerException /*换成Exception就不行了*/{}// 在方法的访问范围,子类可以扩展(业务方面,儿子可以做大做强),但是在异常上,子类只能缩小(儿子犯的错得要是老子能解决的)
    }
    
  4. 在 throws 过程中,若有 try-catch,相当于处理异常,不用再throws了。


自定义异常:

基本概念:

当程序中出现了某些“错误”,但该错误信息并没有在Throwable子类的描述中描述处理,这个时候可以自己设计异常类,用于描述该错误信息。

自定义异常的步骤:

  1. 定义类:自定义异常类型的类名(程序员自己写)继承Exception或RuntimeException;
  2. 若继承Exception则为编译异常;
  3. 若继承RuntimeException,则为运行异常(一般来说继承这个)。
    1. 好处是,我们可以使用默认的处理机制;
    2. 否则我们需要显式地处理。
package com.jiangxian.Exception_.customException;/*** @author JiangXian~* @version 1.0*/
public class CustomException_ {public static void main(String[] args) {int age = 121;if(!(age >= 18 && age <= 120)){throw new ArithmeticException("年龄需要在 18~120之间。");}System.out.println("你的年龄范围正确。");}
}class AgeException extends RuntimeException{public AgeException(String message) { // 构造器super(message);}
}

throw VS throws:

意义位置后面跟的东西
throws异常处理地一种方式方法声明处异常类型
throw手动生成异常对象地关键字方法体中异常对象

Homework:

package com.jiangxian.Exception_.homework;
import java.util.Scanner;/*** @author JiangXian~* @version 1.0*/
public class Homework01 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);while(true){try{System.out.println("请输入第一个整数");String n1 = scanner.next();int num1 = Integer.parseInt(n1);System.out.println("请输入第二个整数");String n2 = scanner.next();int num2 = Integer.parseInt(n2);System.out.println(cal(num1,num2));break;}catch (NumberFormatException e){System.out.println("输入的数不是整数,请重新输入...");}catch(ArithmeticException e){System.out.println("你输入的除数为0...");}}}public static double cal(int n1, int n2){return n1 / n2;}
}

(459/910)

不知不觉已经学完一半啦,比我预想的慢一点~

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

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

相关文章

net某高校社交学习平台的设计与实现

摘 要 高校社交学习平台是一个融合了社交网络特性的在线学习交流系统&#xff0c;旨在促进高校学生之间的信息共享与学习互动。该平台通过提供学习资料、学习视频和学习交流等功能&#xff0c;支持发布学习动态、参与知识问答、并实时追踪学习进度。为学生提供一个全面且便捷的…

七、利用CSS和多媒体美化页面的习题

题目一&#xff1a; 利用CSS技术&#xff0c;结合表格和列表&#xff0c;制作并美化 “ 翡翠阁 ”页面。运行效果如下 运行效果&#xff1a; 代码 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>翡翠阁</title>&…

学习虚幻C++开发日志——委托(持续更新中)

委托 官方文档&#xff1a;Delegates and Lamba Functions in Unreal Engine | 虚幻引擎 5.5 文档 | Epic Developer Community | Epic Developer Community 简单地说&#xff0c;委托就像是一个“函数指针”&#xff0c;但它更加安全和灵活。它允许程序在运行时动态地调用不…

代替Spinnaker 的 POINTGREY工业级相机 FLIR相机 Python编程案例

SpinnakerSDK_FULL_4.0.0.116_x64 是一个用于FLIR相机的SDK&#xff0c;主要用于图像采集和处理。Spinnaker SDK主要提供C接口&#xff0c;无法直接应用在python环境。本文则基于Pycharm2019python3.7的环境下&#xff0c;调用opencv,EasySpin,PySpin,的库实现POINTGREY工业级相…

Linux:自定义Shell

本文旨在通过自己完成一个简单的Shell来帮助理解命令行Shell这个程序。 目录 一、输出“提示” 二、获取输入 三、切割字符串 四、执行指令 1.子进程替换 2.内建指令 一、输出“提示” 这个项目基于虚拟机Ubuntu22.04.5实现。 打开终端界面如图所示。 其中。 之前&#x…

在幸狐picomax SDK里面添加app

本次以onvifserver为例&#xff0c;在在幸狐picomax SDK里面添加app 具体步骤 修改编译器&#xff0c;把CCOMPILE&#xff0c; CPPCOMPILE&#xff0c; LINK 改为对应得编译器 把all 提到前面&#xff0c;保证在make得时候第一个执行得是all标签 install 分几步 创建out文件夹…

如何更改手机GPS定位

你是否曾想过更改手机GPS位置以保护隐私、玩游戏或访问受地理限制的内容&#xff1f;接下来我将向你展示如何使用 MagFone Location Changer 更改手机GPS 位置&#xff01;无论是在玩Pokmon GO游戏、发布社媒贴子&#xff0c;这种方法都快速、简单且有效。 第一步&#xff1a;下…

基于信号量与共享内存实现客户与服务器进程通信

基于信号量与共享内存实现客户与服务器进程通信 发送进程 代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #include <semaphore.h>#define SH…

【AI大模型引领变革】探索AI如何重塑软件开发流程与未来趋势

文章目录 每日一句正能量前言流程与模式介绍【传统软件开发 VS AI参与的软件开发】一、传统软件开发流程与模式二、AI参与的软件开发流程与模式三、AI带来的不同之处 结论 AI在软件开发流程中的优势、挑战及应对策略AI在软件开发流程中的优势面临的挑战及应对策略 结论 后记 每…

机器学习的全面解析:从基础到应用

引言&#xff1a;机器学习的核心地位 机器学习&#xff08;Machine Learning, ML&#xff09;是人工智能&#xff08;AI&#xff09;的核心分支&#xff0c;它通过算法使计算机能够从数据中学习并进行预测或决策。机器学习技术在许多领域都有广泛应用&#xff0c;包括推荐系统、…

Chapter 2 - 16. Understanding Congestion in Fibre Channel Fabrics

Transforming an I/O Operation to FC frames A read or write I/O operation (Figure 2-28) between an initiator and a target undergoes a series of transformations before being transmitted on a Fibre Channel link. 启动程序和目标程序之间的读取或写入 I/O 操作(图…

如何解决Java EasyExcel 导出报内存溢出

如何解决Java EasyExcel 导出报内存溢出 EasyExcel大数据量导出常见方法 1. 分批写入 EasyExcel支持分批写入数据&#xff0c;可以将数据分批加载到内存中&#xff0c;分批写入Excel文件&#xff0c;避免一次性将大量数据加载到内存中。 示例代码&#xff1a; String fileNa…

Qt 的事件投递机制:从基础到实战

在 Qt 开发中&#xff0c;事件系统是核心概念之一&#xff0c;几乎每一个 GUI 应用程序都依赖于它来响应用户操作和系统通知。对于有一定 Qt 基础但首次接触事件投递 (QCoreApplication::postEvent) 的开发者而言&#xff0c;理解事件投递机制尤为重要。这篇博客将带你从基本概…

QDialog中,reject()和close()区别

1. reject()函数 reject()是QDialog类中的一个槽函数&#xff0c;用于以“拒绝”的方式关闭对话框。它通常与对话框的“取消”操作相关联。当调用reject()时&#xff0c;会发出rejected()信号。 行为细节&#xff1a; 从模态对话框的角度来看&#xff0c;当模态对话框调用reje…

【036】基于51单片机五子棋游戏机【Proteus仿真+Keil程序+报告+原理图】

☆、设计硬件组成&#xff1a;51单片机最小系统LCD12864液晶显示按键控制。 1、设计采用STC89C51/52、AT89C51/52、AT89S51/52作为主控芯片&#xff0c;采用LCD12864液晶作为显示&#xff1b; 2、游戏有 人机对战 和 玩家对战 两种模式&#xff0c;玩家白子先下&#xff1b; …

HTML通过JavaScript获取访问连接,IP和端口

<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>Get IP Address</title> <script> function displayURL() { var url window.location.href; // 获取当…

VMWARE虚拟交换机的负载平衡算法

一、基于源虚拟端口的路由 虚拟交换机可根据 vSphere 标准交换机或 vSphere Distributed Switch 上的虚拟机端口 ID 选择上行链路。 基于源虚拟端口的路由是 vSphere 标准交换机和 vSphere Distributed Switch 上的默认负载平衡方法。 ESXi主机上运行的每个虚拟机在虚拟交换…

slam里的体素滤波

SLAM系统通常需要处理大量的传感器数据&#xff0c;如激光雷达&#xff08;LiDAR&#xff09;、相机等获取的数据&#xff0c;这些数据往往包含了大量的冗余信息和噪声。为了提高SLAM系统的效率和准确性&#xff0c;数据预处理是非常重要的一步&#xff0c;体素滤波就是一种常用…

web——sqliabs靶场——第十二关——(基于错误的双引号 POST 型字符型变形的注入)

判断注入类型 a OR 1 1# 发现没有报错 &#xff0c;说明单引号不是闭合类型 测试别的注入条件 a) OR 1 1# a)) OR 1 1# a" OR 11 发现可以用双引号闭合 发现是")闭合 之后的流程还是与11关一样 爆破显示位 先抓包 是post传参&#xff0c;用hackbar来传参 unam…

AI时代,百度的三大主义

现实主义、长期主义、理想主义。 定焦One&#xff08;dingjiaoone&#xff09;原创 作者 | 苏琦 郑浩钧 编辑 | 魏佳 “人工智能很像是一次新的工业革命&#xff0c;这意味着它不会三五年就结束&#xff0c;也不会一两年就出现‘超级应用’&#xff0c;它更像是三五十年对于整…