java学习记录11

异常

在java中提供了处理异常的机制,能够帮助我们避免程序崩溃。

  • Throwable可以用来表示任何可以作为异常抛出的类,分为两种: Error和Exception。
  • 其中Error用来表示JVM无法处理的错误。程序被强制终止。

Exception又分为两种:

受检异常:需要用try...catch..语句捕获并进行处理,并且可以从异常中恢复;

非受检异常:是程序运行时错误,例如除0会引发Arithmetic Exception,此时程序崩溃并且无法恢复。

Throwable

  • Throwable 是 Java语言中所有的错误与异常的超类。
  • Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示发生了异常情况。
  • Throwable 包含了其线程创建时线程线程执行堆栈的快照,它提供了printStackTrace()等接口用于获取堆栈跟踪等信息。

 

Error

  • Error是Java中Throwable类的一个直接子类,表示严重错误,通常是无法恢复的。
  • Error类型的错误通常由Java虚拟机(JVM)或Java运行时环境(JRE)自身引发,而不是程序员引发。
  • 当出现Error时,程序的正常执行流程将被中断,而且无法通过捕获和处理来恢复。
  • 一旦出现Error错误,程序通常会被强制终止,因此,在编写Java程序时,通常不建议显示地捕获和处理Error错误。

Exception

程序本身可以捕获并且可以处理的异常。Exception这种异常又分为两类:运行时异常编译时异常

运行时异常

  • 都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
  • 运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws字句抛出它,也会编译通过。

 编译时异常

是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

 

可查的、不可察的异常

可查的异常(check exception)

  • 在方法声明的throws子句中列出的异常,编译器要求开发人员处理这些异常,要么通过try-catch块捕获并处理,要么通过在方法签名中使用throws关键字声明方法将异常抛出。
  • 可查异常是指在编译时可以即时捕获和处理的异常,这意味着程序员要做出相应的处理,否则编译器会报错。

 例如:IOException、SQLException等都是可查的异常,这些异常通常与外部资源(如文件、网络连接、数据库等)有关。

不可察的异常(unchecked exception)

不可察的异常,也称为运行时异常(runtime exceptions),不要求在方法声明的throws自居中声明或捕获。

运行时异常通常是由程序错误或逻辑错误引起的,而不是外部资源。

当程序出现运行时异常时,它们通常指示程序存在错误或不合理的操作。

例如:NullPointerException、ArrayIndexOutBoundsException、NumberFormatException等都是不可察的异常。 

异常的基本使用

异常关键字

Java异常处理涉及到五个关键字,分别是:try、catch、finally、throw、throws。都不能单独使用。

  • try:用于监听。将要被监听的代码放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
  • catch:用于捕获异常。catch用来捕获try语句块中发生的异常。
  • finally:finally语句块总是会被执行。它主要用于回收在try块里打开的资源(如数据库连接、网络连接和磁盘文件)。只有finally块执行完成之后,才会回来执行try或者catch块中的return和throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
  • throw:用于抛出异常。
  • throws:用在方法签名中,用于声明该方法可能抛出的异常。

 

声明异常

如果一个方法可以导致一个异常但不处理它,它必须使方法的调用者可以保护它们自己而不发生异常。要做到这点,可以在方法声明中包含一个throws语句。一个trhows字句列举了一个方法可能引发的所有异常类型。这对与除了Error或RuntimeException及它们子类以外类型的所有异常是必要的。一个方法可以引发的所有其他类型的异常必须在throws字句中声明,否则会导致编译错误。

在方法中声明一个异常,方法头中使用关键字throws,后面接上要声明的异常。若声明多个异常,则使用逗号分割。

 Throws抛出异常的规则

  • 如果是不受检查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。
  • 必须声明方法可抛出的任何检查异常(checked exception)。即如果一个方法可能出现受可查异常,要么用try-catch语句捕获,要么用throws字句将它抛出,否则会导致编译错误。
  • 仅当抛出了异常,该方法的调用者才必须处理或重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣。
  • 调用方法必须遵循任何可查异常的处理和声明规则。若覆盖(override)一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类。

抛出异常

如果代码可能会引发某种错误,可以创建一个合适的异常类实例并抛出它,这就是抛出异常。

 程序执行完throw语句之后立即停止;throw后面的任何语句不被执行,最邻近的try块用来检查它是否含有一个与异常类型匹配的catch语句。如果发现了匹配的块,控制转向该语句;如果没有发现,次包围的try块来检查,以此类推。如果没有发现匹配的catch块,默认异常处理程序中断程序的执行并且打印堆栈轨迹。

 异常链

异常链就是将异常发生的原因一个传一个连起来,即把底层的异常信息传给上层,逐层抛出。

try {   
    lowLevelOp();   
} catch (LowLevelException le) {   
    throw (HighLevelException) new HighLevelException().initCause(le);   
}

 

当程序捕获到了一个底层异常,在处理部分选择了继续抛出一个更高级别的新异常给此方法的调用者。这样异常的原因就会逐层传递。这样,位于高层的异常递归调用getCause()方法,就可以遍历各层的异常原因。异常链的实际应用很少,发生异常逐层往上抛会消耗大量资源,因为要保存一个完整的异常链信息。

 

自定义异常

使用Java内置的异常类可以描述在编程中出现的大部分异常。除此之外,用户还可以自定义异常。用户自定义异常,只需要继承Exception类即可。

创建自定义异常类,可以分为以下几个步骤:

  • 创建自定义异常类。
  • 在方法中通过throw关键字抛出异常对象。
  • 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字知名要抛出给方法调用者的异常,继续进行下一步操作。
  • 在出现异常方法的调用者中捕获并处理异常。

 

 

 捕获异常

异常捕获常用的处理方法有:

  • try-catch
  • try-catch-finally
  • try-finally
  • try-with-resource

 try-catch

在一个try-catch语句块中可以捕获多个类型的,并对不同类型的异常做出不同的处理。

public static void readFile(String filePath) {
    try {
        // code
    } catch (FileNotFoundException e) {
        // handle FileNotFoundException
    } catch (IOException e){
        // handle IOException
    }
}

同一个catch也可以捕获多种类型异常,用 | 隔开

public static void readFile(String filePath) {
    try {
        // code
    } catch (FileNotFoundException | UnknownHostException e) {
        // handle FileNotFoundException or UnknownHostException
    } catch (IOException e){
        // handle IOException
    }
}

try-catch-finally

try-catch-finally语句块中的finally语句块总是会被执行,除非JVM退出。

try {                        
    //执行程序代码,可能会出现异常                 
} catch(Exception e) {   
    //捕获异常并处理   
} finally {
    //必执行的代码
}
  • 当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句。
  • 当try捕获到异常,catch语句块没有处理此异常的情况:此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行。
  • 当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;

 try-finally

try块中引起异常,异常代码之后的语句不再执行,直接执行finally语句。try块没有引发异常,则执行完try块就执行finally语句。

try-finally可用在不需要捕获异常的代码,可以保证资源在使用后被关闭。例如IO流执行完相应操作后,关闭相应资源;使用Lock对象保证线程同步,通过finally可以保证锁会被释放;数据库连接代码时,关闭连接操作等等。

//以Lock加锁为例,演示try-finally
ReentrantLock lock = new ReentrantLock();
try {
    //需要加锁的代码
} finally {
    lock.unlock(); //保证锁一定被释放
}

finally遇见如下情况不会执行

  • 在前面的代码中用了System.exit()退出程序。
  • finally语句块中发生了异常。
  • 程序所在的线程死亡。
  • 关闭CPU。

 try-with-resource

在finally中的close方法也有可能抛出IOException,从而覆盖了原始异常。Java7提供了一种新的方法来实现资源的自动释放,自动释放的资源需要是实现了AutoCloseable接口的类。

private  static void tryWithResourceTest(){
    try (Scanner scanner = new Scanner(new FileInputStream("c:/abc"),"UTF-8")){
        // code
    } catch (IOException e){
        // handle exception
    }
}

Scanner类如下:

public final class Scanner implements Iterator<String>, Closeable {
  // ...
}
public interface Closeable extends AutoCloseable {
    public void close() throws IOException;
}

try代码块退出时,会自动调用scanner.close方法,和把scanner.close方法放在finally代码块中不同的是,若scanner.close抛出异常,则会被抑制,抛出的仍是原始异常。被抑制的异常会由addSuppressed方法添加到原来的异常,如果想要获取被抑制的异常列表,可以调用getSuppressed方法来获取。

常用的异常

  • RuntimeException
  • java.lang.ArrayIndexOutOfBoundsException:数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
  • java.lang.ArithmeticException:算术条件异常。比如:整数除零等。
  • java.lang.NullPointerException:空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。
  • java.lang.ClassNotFoundException:找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
  • java.lang.NegativeArraySizeException:数组长度为负异常。
  • java.lang.ArrayStor代码eException:数组中包含不兼容的值抛出的异常。
  • java.lang.SecurityException:安全性异常。
  • java.lang.IllegalArgumentException:非法参数异常。
  • IOException
 
  • IOException:操作输入流和输出流时可能出现的异常。
  • EOFException:文件已结束异常。
  • FileNotFoundException:文件未找到异常。
  • 其他
  • ClassCastException:类型转换异常类
  • ArrayStoreException:数组中包含不兼容的值抛出的异常
  • SQLException:操作数据库异常类
  • NoSuchFieldException:字段未找到异常
  • NoSuchMethodException:方法未找到抛出的异常
  • NumberFormatException:字符串转换为数字抛出的异常
  • StringIndexOutOfBoundsException:字符串索引超出范围抛出的异常
  • IllegalAccessException:不允许访问某类异常
  • InstantiationException:当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常

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

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

相关文章

IDEA如何导入项目,包括从git仓库(github)导入项目

前言 大家好&#xff0c;我是小徐啊。自从使用了IDEA开发Java应用后&#xff0c;我再也不想使用eclipse了。IDEA的好处真的太多了。今天小徐就来介绍下IDEA的入门知识&#xff0c;也就是如何导入一个项目。 IDEA如何导入项目 首先&#xff0c;打开IDEA&#xff0c;点击上方的…

GitLab|数据迁移

注意&#xff1a;新服务器GitLab版本需和旧版本一致 在旧服务器执行命令进行数据备份 gitlab-rake gitlab:backup:create 备份数据存储在 /var/opt/gitlab/backups/ 将备份数据传输到新服务器的/var/opt/gitlab/backups/下&#xff0c;并修改文件权限&#xff08;下载前和上传…

SSRF漏洞利用

2.漏洞利用 2.1 SSRF中URL的伪协议 file:// 从⽂件系统中获取⽂件内容&#xff0c;如&#xff0c;file:///etc/passwd dict:// 字典服务器协议&#xff0c;访问字典资源&#xff0c;如dict://ip:6379/info sftp:// ssh⽂件传输协议或安全⽂件传输协议 ldap:// 轻量级⽬录访问…

flux代码解析

https://zhuanlan.zhihu.com/p/714150390https://zhuanlan.zhihu.com/p/714150390 flux.1[pro] 1.版本 flux.1 [pro] api收费版本 flux.1 [dev] flux.1 蒸馏版本 guidance-distilled模型 flux.1 [schell] 1-4步版本 2.通读代码框

Scala之Array数组

可修改的Array import scala.collection.mutable.ArrayBuffer //Array:数组 //可修改的&#xff1a;ArrayBuffer //不可修改的&#xff1a;Array object Test1 {//可修改的&#xff1a;ArrayBufferdef main(args: Array[String]): Unit {//1.新建val arr1 ArrayBuffer(1,2,3)…

PostgreSQL常用字符串函数与示例说明

文章目录 coalesce字符串位置(position strpos)字符串长度与大小写转换去掉空格(trim ltrim rtrim)字符串连接(concat)字符串替换简单替换(replace)替换指定位置长度(overlay)正则替换(regexp_replace) 字符串匹配字符串拆分split_part(拆分数组取指定位置的值)string_to_array…

Elasticsearch 中的热点以及如何使用 AutoOps 解决它们

作者&#xff1a;来自 Elastic Sachin Frayne 探索 Elasticsearch 中的热点以及如何使用 AutoOps 解决它。 Elasticsearch 集群中出现热点的方式有很多种。有些我们可以控制&#xff0c;比如吵闹的邻居&#xff0c;有些我们控制得较差&#xff0c;比如 Elasticsearch 中的分片分…

unity3d——基础篇小项目(开始界面)

示例代码&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine;public class BeginPanel : BasePanel<BeginPanel> {public UIButton btnBegin;public UIButton btnRank;public UIButton btnSetting;public UIButton btnQuit; …

不用手绘不用PS!如何一键生成波谱风插画?两个方法

​ 以前我们制作一张波谱风插画既要手绘又要用ps处理&#xff0c;现在我们直接用AI一键生成。接下来我用两个方法带你快速生成波谱风插画&#xff0c;一个是通过Midjourney&#xff0c;另一个是利用ComfyUI的工作流。话不多说&#xff0c;直接上干货。 波谱风插画是什么&#x…

推荐一款专业电脑护眼工具:CareUEyes Pro

CareUEyes Pro是一款非常好用的专业电脑护眼工具&#xff0c;软件小巧&#xff0c;界面简单&#xff0c;它可以自动过滤电脑屏幕的蓝光&#xff0c;让屏幕显示更加的不伤眼&#xff0c;更加舒适&#xff0c;有效保护你的眼睛&#xff0c;可以自定义调节屏幕的色调&#xff0c;从…

Ubuntu ESP32开发环境搭建

文章目录 ESP32开发环境搭建安装ESP-IDF搭建一个最小工程现象 ESP32开发环境搭建 最近有个小项目需要用到能够联网的mcu驱动&#xff0c;准备玩玩esp的芯片&#xff0c;记录下ESP32开发环境搭建的过程。 ESP-IDF 是乐鑫科技为其 ESP32 系列芯片提供的官方开发框架。这个框架主…

更改ArduSub水平位置控制器为ADRC

水平位置控制器的函数为update_xy_controller(),位于libraries/AC_AttitudeControl/AC_PosControl.cpp,现在的控制器为p-pid,p控制器将位置信息转化为速度信息,pid控制器将速度信息转化为加速度信息,然后在送给姿态控制器。 现在将当前的P控制器转化为ADRC控制器,其他的更…

ubuntu中使用ffmpeg和nginx推流rtmp视频

最近在测试ffmpeg推流rtmp视频&#xff0c;单独安装ffmpeg是无法完成推流的&#xff0c;需要一个流媒体服务器&#xff0c;常用nginx&#xff0c;可以直接在ubuntu虚拟机里面测试一下。 测试过程不涉及编译ffmpeg和nginx&#xff0c;仅使用基本功能&#xff1a; 1 安装ffmpeg …

图像处理 之 凸包和最小外围轮廓生成

“ 最小包围轮廓之美” 一起来欣赏图形之美~ 1.原始图片 男人牵着机器狗 2.轮廓提取 轮廓提取 3.最小包围轮廓 最小包围轮廓 4.凸包 凸包 5.凸包和最小包围轮廓的合照 凸包和最小包围轮廓的合照 上述图片中凸包、最小外围轮廓效果为作者实现算法生成。 图形几何之美系列&#…

【Nginx从入门到精通】05-安装部署-虚拟机不能上网简单排错

文章目录 总结1、排查步骤 一、排查&#xff1a;Vmware网关二、排查&#xff1a;ipStage 1 &#xff1a;ping 127.0.0.1Stage 2 &#xff1a;ping 宿主机ipStage 3 &#xff1a;ping 网关 失败原因解决方案Stage 4 &#xff1a;ping qq.com 总结 1、排查步骤 Vmware中网关是否…

Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画

Python Turtle召唤童年&#xff1a;喜羊羊与灰太狼之懒羊羊绘画 &#x1f438; 前言 &#x1f438;&#x1f41e;往期绘画&#x1f41e;&#x1f40b; 效果图 &#x1f40b;&#x1f409; 代码 &#x1f409; &#x1f438; 前言 &#x1f438; 小时候&#xff0c;每次打开电视…

机器学习问题之一:协变量偏移(Covariate Shift)

协变量偏移&#xff08;Covariate Shift&#xff09;是机器学习和深度学习中的一个重要概念&#xff0c;指的是在模型训练和应用时&#xff0c;输入数据&#xff08;特征&#xff09;的分布发生了变化&#xff0c;但输出标签的分布保持不变。这会导致模型在训练集上表现良好&am…

【UGUI】Unity 背包系统实现02:道具信息提示与显示

在游戏开发中&#xff0c;背包系统是一个常见的功能模块&#xff0c;用于管理玩家拾取的物品。本文将详细介绍如何在 Unity 中实现一个简单的背包系统&#xff0c;包括道具信息的提示和显示功能。我们将通过代码和场景搭建来逐步实现这一功能。 1. 功能需求清单 在实现背包系…

nodejs入门(1):nodejs的前后端分离

一、引言 我关注nodejs还是从前几年做了的一个电力大数据展示系统开始的&#xff0c;当然&#xff0c;我肯定是很多年的计算机基础的&#xff0c;万变不离其宗。 现在web网站都流行所谓的前后端结构&#xff0c;不知不觉我也开始受到这个影响&#xff0c;以前都是前端直接操作…

go语言闭包捕获的是变量的引用而不是变量的值

在 Go 语言中&#xff0c;闭包捕获的是变量的引用&#xff0c;而不是变量的值。这意味着闭包会引用循环变量或外部变量的实际内存位置&#xff0c;而不是在闭包创建时复制变量的值。这种行为有时会导致意外的结果&#xff0c;尤其是在循环中创建多个闭包时。 闭包捕获变量的引…