如何以及何时使用例外

本文是我们名为“ 高级Java ”的学院课程的一部分。

本课程旨在帮助您最有效地使用Java。 它讨论了高级主题,包括对象创建,并发,序列化,反射等。 它将指导您完成Java掌握的过程! 在这里查看 !

目录

1.简介 2.异常以及何时使用它们 3.已检查和未检查的异常 4.使用尝试资源 5.异常和lambda 6.标准Java异常 7.定义自己的例外 8.记录例外 9.异常和记录 10.下一步是什么 11.下载源代码

1.简介

Java中的异常是在程序流中发出异常(或异常)情况信号的重要工具,可能会阻止其进一步发展。 从本质上讲,那些特殊情况可能是致命的(程序无法再运行,应该终止)或可恢复(程序可能会继续运行,尽管某些功能可能不可用)。

在本教程的这一部分中,我们将逐步介绍在Java中使用异常的典型场景,讨论已检查和未检查的异常,并探讨一些极端情况和有用的习惯用法。

2.异常以及何时使用它们

简而言之,异常是某种事件(或信号),它们在程序执行期间发生并中断常规执行流程。 导致引入异常的想法是对过去使用的错误代码和状态检查技术的替代。 从那时起,异常被广泛接受为处理包括Java在内的许多编程语言中的错误情况的标准方法。

只有一个与异常处理相关的重要规则(不仅在Java中):永远不要忽略它们! 每个异常都应至少记录一次(请参阅Exceptions和logging ),但永远不要忽略。 尽管如此,在某些罕见的情况下,可以安全地忽略异常,因为实际上可以做很多事情(请参阅示例中的使用try-with-resources部分)。

另外,在本教程的第6部分“ 如何有效地编写方法”中 ,我们讨论了参数验证和健全性检查。 异常是这些实践的关键部分:每种公共方法都应在进行任何实际工作之前验证所有必需的前提条件,如果某些条件未满足,则提出适当的例外条件。

3.已检查和未检查的异常

Java语言中的异常管理与其他编程语言不同。 这主要是因为Java中有两类异常: 选中的异常和未选中的异常。 有趣的是,这两个类在某种程度上是人为的,是由Java语言规则及其编译器强加的(但是JVM在它们之间没有区别)。

根据经验,未经检查的异常用于表示与程序逻辑和所做假设有关的错误条件(无效参数,空指针,不支持的操作,等等)。 任何未经检查的异常都是RuntimeException的子类,这就是Java编译器如何理解特定异常属于未经检查的异常的类。

未经检查的异常不需要被调用方捕获,也不必被列为方法签名的一部分(使用throws关键字)。 NullPointerException是未经检查的异常的最著名的成员,这是Java标准库中的声明:

public class NullPointerException extends RuntimeException {public NullPointerException() {super();}public NullPointerException(String s) {super(s);}
}

因此,检查的异常表示程序无法直接控制的区域(如内存,网络,文件系统等)中的无效条件。 任何检查到的异常都是Exception的子类。 与未检查的异常相反,已检查的异常必须被调用者捕获,或者被列为方法签名的一部分(使用throws关键字)。 IOException可能是检查异常中最知名的一种:

public class IOException extends Exception {public IOException() {super();}public IOException(String message) {super(message);}public IOException(String message, Throwable cause) {super(message, cause);}public IOException(Throwable cause) {super(cause);}
}

在当时,将已检查和未检查的异常分开听起来是个好主意,但是多年来,事实证明,它引入了更多样板代码,而不是解决实际问题的漂亮代码模式。 Java生态系统中出现的典型(不幸的是,非常麻烦)模式是将未检查的异常隐藏(或包装)在未检查的异常中,例如:

try {// Some I/O operation here
} catch( final IOException ex ) {throw new RuntimeException( "I/O operation failed", ex );
}

这不是最好的选择,但是如果精心设计自己的异常层次结构,可能会减少开发人员需要编写的样板代码数量。

值得一提的是,Java中还有另一类异常扩展了Error类(例如, OutOfMemoryErrorStackOverflowError )。 这些异常通常表明致命的执行失败,导致无法立即从此类错误情况中恢复,从而导致程序立即终止。

4.使用尝试资源

抛出的任何异常都会导致一些所谓的堆栈展开和程序执行流程的更改。 结果是与未封闭的本机资源(例如文件句柄和网络套接字)有关的可能的资源泄漏。 Java中行为良好的典型I / O操作(直到版本7)需要使用强制性的finally块来执行清理,并且通常看起来像这样:

public void readFile( final File file ) {InputStream in = null;try {in = new FileInputStream( file );// Some implementation here} catch( IOException ex ) {// Some implementation here} finally {if( in != null ) {try {in.close();} catch( final IOException ex ) {/* do nothing */}}}
}

尽管如此, finally块看起来确实很丑陋(不幸的是,此处无法做太多事情,因为在输入流上调用close方法也可能导致IOException异常),无论尝试关闭输入流(并释放背后的操作系统资源)发生了什么情况它)将被执行。 在“ 异常以及何时使用它们 ”一节中,我们强调了一个事实,即永远都不应忽略异常,但是,用close方法抛出的异常可以说是该规则的唯一排除项。

幸运的是,自Java 7以来,该语言引入了一种名为try-with-resources的新结构,该结构大大简化了整体资源管理。 这是上面使用try-with-resources重写的代码片段:

public void readFile( final File file ) {try( InputStream in = new FileInputStream( file ) ) {// Some implementation here} catch( final IOException ex ) {// Some implementation here}
}

为了在try-with-resources块中使用该资源,唯一需要拥有的就是接口AutoCloseable 。 在后台Java编译器将此构造扩展为更复杂的结构,但对开发人员而言,代码看起来非常易读和简洁。 请在适当的地方使用此非常方便的技术。

5.异常和lambda

在本教程的第3部分如何设计类和接口中 ,我们已经讨论了Java 8的最新和最出色的功能,特别是lambda函数。 但是,我们尚未深入研究许多实际用例,并且例外是其中之一。

毫无疑问,未检查的异常可以按预期工作,但是Java的lambda函数语法不允许指定可能抛出的已检查的异常(除非这些异常由@FunctionalInterface本身定义)。 以下代码段将不会以编译错误“未处理的异常类型IOException”进行编译(可能会在第03行抛出):

public void readFile() {run( () -> {Files.readAllBytes( new File( "some.txt" ).toPath() );} );}public void run( final Runnable runnable ) {runnable.run();}

现在唯一的解决方案是在lambda函数体内捕获IOException异常,然后重新抛出适当的RuntimeException异常(不要忘记将原始异常作为原因传递),例如:

public void readFile() {run( () -> {try {Files.readAllBytes( new File( "some.txt" ).toPath() );} catch( final IOException ex ) {throw new RuntimeException( "Error reading file", ex );}} );
}

声明了许多功能接口,可以从其实现中引发任何异常,但是如果没有(如Runnable),则将检查的异常包装(或捕获)为非检查的异常是唯一的方法。

6.标准Java异常

Java标准库提供了大量关于异常的类,这些异常类被指定为覆盖程序执行期间发生的大多数通用错误。 下表列出了使用最广泛的应用程序,请在定义您自己的应用程序之前考虑它们。

例外类别 目的
NullPointerException 在需要对象的情况下尝试使用null
IllegalArgumentException 方法已传递了非法或不适当的参数。
IllegalStateException 方法已在非法或不适当的时间被调用。
IndexOutOfBoundsException 某种索引(例如,数组,字符串或向量)的索引超出范围。
UnsupportedOperationException 不支持请求的操作。
ArrayIndexOutOfBoundsException 已使用非法索引访问了数组。
ClassCastException 代码已尝试将对象强制转换为不是实例的子类。
EnumConstantNotPresentException 试图访问一个enum的名称和常量enum类型包含具有指定名称的常量( enums一直在本教程中, 部分5 如何以及何时使用枚举和注解 )。
NumberFormatException 尝试将字符串转换为数字类型之一,但是该字符串没有适当的格式。
StringIndexOutOfBoundsException 索引为负或大于字符串的大小。
IOException 发生了某种I / O异常。 此类是由失败或中断的I / O操作产生的异常的一般类别。

表1 –标准Java异常

7.定义自己的例外

Java语言使定义自己的异常类非常容易。 精心设计的异常层次结构允许实施详细且细粒度的错误条件管理和报告。 与往常一样,找到合适的平衡非常重要:太多的异常类会使开发复杂化,并浪费大量的代码来捕获异常或将异常传播到堆栈中。

强烈建议所有用户定义的异常都应继承自RuntimeException类,并属于未经检查的异常类(但是,规则中始终存在排除项)。 例如,让我们定义异常以进行身份​​验证拨号:

public class NotAuthenticatedException extends RuntimeException {private static final long serialVersionUID = 2079235381336055509L;public NotAuthenticatedException() {super();}public NotAuthenticatedException( final String message ) {super( message );}public NotAuthenticatedException( final String message, final Throwable cause ) {super( message, cause );}
}

此异常的目的是在信号插入过程中发出有关不存在或无效的用户凭据的信号,例如:

public void signin( final String username, final String password ) {if( !exists( username, password ) ) {throw new NotAuthenticatedException("User / Password combination is not recognized" );}
}

将信息性消息与异常一起传递始终是一个好主意,因为它有助于对生产系统进行故障排除。 同样,如果异常是由于另一个特殊情况导致的,则应使用cause构造函数参数保留初始异常。 这将有助于找出问题的真正根源。

8.记录例外

在本教程的第6部分“ 如何高效地编写方法”中 ,我们介绍了Java方法的正确文档。 在本节中,我们将花更多的时间讨论如何使异常成为文档的一部分。

如果方法作为其实现的一部分可能引发检查的异常,则它必须成为方法签名的一部分(使用throws声明)。 Java文档工具分别具有@throws标记,用于描述这些异常。 例如:

/*** Reads file from the file system.* @throws IOException if an I/O error occurs.*/
public void readFile() throws IOException {// Some implementation here
}

相反,正如我们从Checked和unchecked异常一节中所知道的那样,未经检查的异常通常不声明为方法签名的一部分。 但是,记录它们仍然是一个非常好的主意,因此方法的调用者将意识到可能引发的异常(使用相同的@throws标记)。 例如:

/*** Parses the string representation of some concept.* @param str String to parse* @throws IllegalArgumentException if the specified string cannot be parsed properly* @throws NullPointerException if the specified string is null*/
public void parse( final String str ) {// Some implementation here
}

请始终记录您的方法可能引发的异常。 它将帮助其他开发人员从一开始就实施适当的异常处理和恢复(后备)逻辑,从而避免他们对生产系统中的问题进行故障排除。

9.异常和记录

日志记录( http://en.wikipedia.org/wiki/Logfile )是或多或少复杂的Java应用程序,库或框架的重要组成部分。 它是应用程序中发生的重要事件的日志,异常是此流程的关键部分。 在本教程的后面,我们可能会介绍Java标准库提供的日志子系统,但是请记住,以后应该正确记录和分析异常,以便发现应用程序中的问题并解决关键问题。

10.下一步是什么

在本教程的这一部分中,我们介绍了异常,这是Java语言的一个非常重要的功能。 我们已经看到异常是Java中错误管理的基础。 异常使处理和发信号通知错误的情况变得非常容易,并且与错误代码,标志和状态相反,一旦发生,则不能忽略异常。 在下一部分中,我们将讨论一个非常热门和复杂的主题:Java中的并发和多线程编程。

11.下载源代码

这是关于如何以及何时使用异常的课程。 您可以在此处下载源代码: advanced-java-part-8

翻译自: https://www.javacodegeeks.com/2015/09/how-and-when-to-use-exceptions.html

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

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

相关文章

域前置 配置cdn-解决HTTPS-SSL通讯被朔源IP封锁问题

域前置 配置cdn URL -解决HTTPS-SSL通讯被朔源IP封锁问题 https://mp.weixin.qq.com/s/MghFgegdp3l3tFE3hOvcYw

深入理解Java引用类型

深入理解Java引用类型 在Java中类型可分为两大类:值类型与引用类型。值类型就是基本数据类型(如int ,double 等),而引用类型,是指除了基本的变量类型之外的所有类型(如通过 class 定义的类型)。所有的类型在…

值得一谈的鸿蒙2.0,程序员们拿起你们手中的编译器撸一下hello world

一款“面向未来”、面向全场景(移动办公、运动健康、社交通信、媒体娱乐等)的分布式操作系统 。现已开源,名为OpenHarmony。 2019年8月9日,华为在HDC开发者大会上正式发布鸿蒙系统。 2020年9月10日,华为在HDC开发者大会上如约发布鸿蒙 2.0,并面向应用开发者发布Beta版本…

GitHack使用方法

ctf小白刚下载这个,不知道怎么用。现在会用啦就记录一下~ 下载地址:https://github.com/lijiejie/GitHack 下载下来后,通过cmd使用,如下图所示: 总结(命令): GitHack.py http://XXXX…

工厂方法模式和抽象工厂模式

有一个抽象的产品类 Product 具体的产品类 Product1 Product2.。。。 工厂方法&#xff1a; 1、创建抽象的工厂类&#xff1a;Creator&#xff1a; public abstract class Creator{ public abstract <T extends Product> T createProduct(Class<T> c); } 2、具体实…

值得一谈的鸿蒙2.0,赶紧撸一下hello world

一款“面向未来”、面向全场景&#xff08;移动办公、运动健康、社交通信、媒体娱乐等&#xff09;的分布式操作系统 。现已开源&#xff0c;名为OpenHarmony。2019年8月9日&#xff0c;华为在HDC开发者大会上正式发布鸿蒙系统。2020年9月10日&#xff0c;华为在HDC开发者大会上…

key 和secret_Java Secret:加载和卸载静态字段

key 和secret总览 首先&#xff0c;很自然地假设静态字段具有特殊的生命周期&#xff0c;并且在应用程序的生命周期中一直存在。 您可以假设它们存在于内存中的特殊位置&#xff0c;例如C或类元信息的perm gen中的内存开始。 但是&#xff0c;得知静态字段驻留在堆上&#xff…

【Jenkins】未授权访问漏洞

一、漏洞介绍 1 ) Jenkins介绍 Jenkins是一个基于Java开发的开源项目&#xff0c;可在Tomcat等流行的servlet容器中运行&#xff0c;也可以独立运行&#xff0c;其功能如下&#xff1a; 用于持续性、自动的构建/测试软件项目监控或跑一些定时任务监控外部调用执行的工作 2 …

java split函数应该注意的问题

split函数的参数是一个String&#xff0c;但是这个String会被解释成一个正则表达式. 比如 "test.txt".split(".").length得到的值是0&#xff0c;因为在正则表达式中点号会被当作一个通配符, 所以得不到结果&#xff0c; 正确的写法应该是 "test.txt&…

解决谷歌浏览器F12打不开调试页面的问题。

最近应用着急上线&#xff0c;需要批量测试&#xff0c;发现F12不好使啦。 解决办法&#xff1a; 1.找到谷歌浏览器&#xff1a;设置-扩展程序-开发者模式。关闭。 2.刷新浏览器或者重启浏览器后&#xff0c;打开需要调试的页面&#xff0c;鼠标点一下地址栏&#xff0c;按F1…

还有另一个报告生成器?

如果您具有业务应用程序开发的经验&#xff0c;那么很可能会遇到要求该应用程序具有灵活的报告机制的需求。 我工作的公司主要专注于开发业务解决方案&#xff0c;而报告是必不可少的&#xff0c;的确&#xff0c;它必须包含我们开发的所有企业系统的方面。 为了在我们的系统中…

ARL资产侦察灯塔系统搭建及使用

ARL资产侦察灯塔系统搭建及使用 ARL&#xff08;Asset Reconnaissance Lighthouse&#xff09;资产侦查灯塔旨在快速发现并整理企业外网资产并为资产构建基础数据库&#xff0c;无需登录凭证或特殊访问即可主动发现并识别资产&#xff0c;让甲方安全团队或者渗透测试人员快速寻…

window电脑关闭自动更新的方法,妈妈再也不用担心我开机等电脑啦

公司的新电脑&#xff0c;每次关机开机都会更新&#xff0c;今天更新了3次&#xff0c;每次半小时&#xff0c;我忍不了&#xff0c;赶紧关闭自动更新。 1.winR打开面板输入services.msc&#xff0c;然后回车。 2.找到windows Update,右键找到 属性。 3.把启动类型改为“禁用”…

C#中 Convert与Parse的区别

1.Convert.ToDouble与Double.Parse的区别。实际上Convert.ToDouble与 Double.Parse 较为类似&#xff0c;实际上 Convert.ToDouble内部调用了 Double.Parse&#xff1a; (1)对于参数为null的时候&#xff1a;Convert.ToDouble参数为 null 时&#xff0c;返回 0.0&#xff1b; D…

常见的Web源码泄漏漏洞

常见的Web源码泄漏漏洞 1.Git 源码泄露 ​ 开发人员会使用 git 进行版本控制&#xff0c;对站点自动部署。但如果配置不当&#xff0c;可能会将 .git 文件夹直接部署到线上环境&#xff0c;这就引起了 git 泄露漏洞&#xff0c;我们可以利用这个漏洞直接获得网页源码 简要介…

我是如何解决电脑连接WiFi提示无线适配器或访问点有问题

今天国庆后第一天上班&#xff0c;打开电脑一直连接不上我手机的热点&#xff0c;提示无线适配器或访问点有问题。可能是由于重启电脑自动更新系统的缘故&#xff0c;关闭电脑自动更新的办法请参考我的上一篇文章&#xff1a;window电脑关闭自动更新的方法 不说废话&#xff0…

WebCombo 客户端绑定数据

///绑定webcombo1 var cbo igcmbo_getComboById(<%this.WebCombo2.ClientID %>); for (var i 0; i <4; i) { var row igtbl_addNew(cbo.grid.Id, 0); row.getCell(0).setValue("0.91");…

java ee cdi_Java EE6 CDI,命名组件和限定符

java ee cdiJava EE6的最大承诺之一就是简化了依赖注入的使用。 他们做到了&#xff0c;使用CDI 。 CDI代表Java EE的上下文和依赖注入&#xff0c;它提供了一个基础集&#xff0c;用于在企业应用程序中应用依赖注入。 在CDI之前&#xff0c;EJB 3还引入了依赖注入&#xff0c;…

如何使用git下载别人在github的代码?

今天东哥让我帮他们公司检查一下几十款产品的前端代码&#xff0c;我用新电脑作业了一下&#xff0c;简单分享git如何下载别人的代码。 完整教程请参考我上篇文章&#xff1a;——> Git教程学习总结 首先本地有git环境。打开git bash here。 查看一下版本 初始化git使…

AppScan的安装与使用

AppScan的安装与使用 实验环境&#xff1a;Win7 Win2k8 将软件包复制到这个目录下&#xff1a; 双击 复制到C盘&#xff1a; 复制到C盘的这个目录下&#xff0c;并替换&#xff1a; 然后到菜单栏中&#xff0c;双击查看&#xff1a; 这样就可以使用了: 使用App…