2016 - 2024

感恩一路有你

java如何优雅的处理异常 Java是c 实现的,为啥Java的异常处理更完善?

浏览量:3560 时间:2023-04-30 07:53:11 作者:采采

Java是c 实现的,为啥Java的异常处理更完善?

这话很没理由,那第一个低级语言编译器应该机器语言实现的呢,为啥功能越来越大系统完善?

现在的编译器很多都是自举,用老版本开发新版本,功能又是更加完善系统

当然是越标准封装越系统完善啊,这跟用什么实现方法完全没有关系,不是他所有的机制一定会是底层直接可以提供的

Java的trycatch也可以能捕捉全部异常,c的trycatch没有办法去捕获部分十分,Java是怎么能够做到的?

究竟你说的”更完善系统”具体指的是什么?你问题不说很清楚怎么回答我?

如何优雅的设计Java异常?

异样的类别

正如我们所明白的,java中的异样的超类是(后文省略为Throwable),它有两个都很有用的子类,(后文省略为Exception)和(后文省略为Error),其中Error由JVM虚拟机进行管理,如我们所熟知的OutOfMemoryError十分等,因为我们本文不了解Error无比,那你我们细说一下Exception异常。

Exception异样有个比较好最重要的子类,叫做什么RuntimeException。我们将RuntimeException或其他继承自RuntimeException的子类一般称非受检异样(invalidException),其他继承自Exception异样的子类一般称受检十分(blockedException)。本文重点来关注看看受检异常和非受检异样这两种极其。

该如何选择异常

从笔者的开发经验来看,如果不是在一个应用中,必须旗下一个方法(如某个功能的service方法),这个方法假如中间肯定出现异样,这样的话你必须判断这个无比又出现之后有无全局函数者可以不如何处理,而且你是否需要如果能全局函数者并且处理,如果不是动态链接库者也可以如何处理,但是你也希望内部函数者通过处理,那就就要抛出受检异常,警告动态创建者在不使用你的方法时,判断到要是掷下异常时如果接受处理。

几乎完全一样的,如果在写某个方法时,你以为这是个无意中十分,理论上说,你觉着运行时很可能会出现什么问题,而这些问题或许并非定然再一次发生的,也不要全局函数者总是显示的通过异常来确认业务流程你操作的,那你这时就可以使用一个RuntimeException这样的非受检异样.

再说,估计也我上边说的这段话,你读了很多遍也始终总觉得艰涩了。

那么,请领着我的思路,在慢慢仔细体会帮一下忙。

什么时候才要抛异样

首先我们是需要打听一下一个问题,什么时候才不需要抛异常?异常的设计是方便给开发者在用的,但并非乱是用,笔者相对于什么时候抛无比这个问题也问了很多朋友,能给出确切答案的倒是不多。反正这个问题很简单,如果不是你总觉得某些”问题”帮忙解决不了了,那就你就是可以抛出异常了。

比如,你在写一个service,其中在写到某段代码处,你发现到很可能会有一种问题,那么就请甩出异常吧,不会相信我,你此时甩出十分将是一个最佳的方法时机。

应该要丢出整样的极其

打听一下完了什么时候才要一抛异常后,我们再认真思索一个问题,真的当我们抛出异常时,我们应该是选用比较整样的极其呢?到底是是受检十分还是非受检异常呢(RuntimeException)呢?

我来通俗的解释帮一下忙这个问题,先从受检异样你说起,假如有那样的话一个业务逻辑,不需要从某文件中读取数据某个数据,这个加载能操作可能会是由于文件被删除掉等其他问题导致没能获取使再次出现读取数据错误,那么还得从redis或mysql数据库中再去资源此数据,参考万分感谢代码,getKey(Integer)为入口程序.

可以了,看了以上代码以后,你或许心中有一些想法,原来受检十分这个可以控制义务逻辑,对,是啊,按照受检异常真的可以不操纵业务逻辑,可是千万记住千万不能这样在用,我们应该是合不合理的甩出异常,是因为程序本身才是流程,异样的作用单单是当你通过不出去的时候能找到的一个借口只不过是,它并不能不能以为压制程序流程的入口或出口,如果不是这样的使用的话,是在将异常的作用逐渐扩大化,这样的可以说会造成代码复杂程度的增加,耦合性会增加,代码可读性减低等问题。

那么就肯定会别可以使用这样的无比吗?不过也不是,在是真的有这样的需求的时候,我们可以这样的在用,只是千万记住,不要把它真有当作完全控制流程的工具或手段。这样也不知什么时候才要丢出这样的极其呢?要考虑到,如果不是动态创建者调用程序出错后,一定得让动态链接库者对此错误通过处理才是可以,柯西-黎曼方程这样的要求时,我们才能够考虑使用受检异样。

接下来,我们来看一下非受检十分呢(RuntimeException),相对于RuntimeException这种极其,我们当然很多见,比如说/等,这样的话这种无比我们时候掷下呢?

当我们在写某个方法的时候,肯定会偶然路过遇到某个错误,我们其实这个问题时不运行时肯定为发生的,而且理论上讲,没有这个问题的话,程序将是都正常想执行的时候,它不噬灵鬼斩具体的要求动态链接库者一定得能捕捉这个异常,此时抛出RuntimeException十分。

举个例子,当传来一个路径的时候,需要回一个路径填写的File对象:

上述事项例子是因为,如果全局函数者内部函数getFiles(String)的时候如果不是path是空,那就就抛出空指针极其(它是RuntimeException的子类),全局函数者不用什么显示的接受try…catch…操作进行强制破军处理.这就要求全局函数者在调用这样的方法时先进行验证,尽量减少再一次发生RuntimeException.追加:

估计最好选择哪种极其

实际以上的描述和举例说明,可以总结归纳出一个结论,RuntimeException异常和受检无比之间的区别应该是:是否是强制具体的要求调用者需要去处理此异常,要是噬魂之手具体的要求调用者要进行处理,这样的话就可以使用受检极其,不然就选择类型非受检无比(RuntimeException)。好象来讲,假如没有特殊的方法的要求,我们我建议你使用RuntimeException十分。

场景推荐和技术选型架构描述

很显然我们所知,比较传统的项目全是以MVC框架为基础接受开发的,本文主要从建议使用restful风格接口的设计来可以体验帮一下忙异常处理的优雅。

我们把关注点放在restful的api层(和web中的controller层带有)和service层,想研究一下在service中如何一抛十分,后再api层如何通过捕捉猎物因此转化异常。

建议使用的技术是:spring-boot,jpa(hibernate),mysql,如果不是对这些技术又不是太熟得不能再熟,读者必须一一泛读相关材料。

业务场景描述

选择一个也很最简单业务场景,以电商中的收货地址管理为例,用户在移动端参与购买商品时,要并且收货地址管理,在项目中,提供给一些给移动端进行访问的api接口,如:直接添加收货地址,删除收货地址,更改后收货地址,默认收货地址设置,收货地址列表可以查询,单个确认发货地址查询等接口。

统合约束条件

可以啦,这个是设置好的一个很基本的业务场景,肯定,无论什么样的api操作,其中都中有一些规则:

添加收货地址:入参:

用户id

收货地址实体信息

加以约束:

用户id不能为空,且此用户虽然是修真者的存在的

收货地址的没有必要字段没法为空

假如用户还没有收货地址,当此收货地址创建时设置里成默认收货地址—

删除收货地址:入参:

用户id

收货地址id

强制力:

用户id没法为空,且此用户倒是是未知的

收货地址又不能为空,且此收货地址倒是是存在地的

确认此收货地址是否是用户的收货地址

可以确定此收货地址是否需要为默认收货地址,要是是设置成收货地址,这样的话又不能通过删掉

你要改收货地址:入参:

用户id

收货地址id

约束:

用户id不能不能为空,且此用户的确是存在的

收货地址没法为空,且此收到货地址倒是是存在的

推测此收货地址如何确定是用户的收货地址

设置成地址设置:入参:

用户id

收货地址id

管理和约束:

用户id不能为空,且此用户确实是是修真者的存在的

收货地址不能为空,且此收货地址虽然是修真者的存在的

可以确定此收货地址是否是是用户的收货地址

收货地址列表网上查询:入参:

用户id

约束力:

用户id不能不能为空,且此用户倒是是未知的

单个收货地址查询:入参:

用户id

收货地址id

强制力:

用户id不能不能为空,且此用户虽然是存在的

收货地址不能为空,且此收货地址确实是是未知的

判断此收货地址是否是用户的收货地址

强制力判断和技术选型

对此根据上述规定列下的约束条件和功能列表,我选择几个都很典型的异常处理场景并且分析:直接添加收货地址,彻底删除收货地址,资源收货地址列表。

这样的话应该要有哪些必要的知识储备呢,让我们查查收货地址这个功能:

再添加收货地址中必须对用户id和收货地址实体信息就行校验,那就相对于非空的判断,我们怎么接受工具的选择呢?比较传统的判断如下:

上边的例子,如果只判断uid为空好在,要是再去判断address这个实体中的某些必要属性是否需要为空,在字段很多的情况下,这说白是灾难性的。

那我们应该要怎摸并且这些入参的判断呢,给大家可以介绍两个知识点:

Guava中的Preconditions类实现了很多入参方法的判断

jsr303的validation规范(目前实现程序都很全的是hibernate实现程序的hibernate-validator)

如果没有使用了这两种推荐技术,那么入参的判断会变得异常简单点比较多。推荐一下大家多在用这些成熟的技术和jar工具包,他可以不会减少很多不必要的工作量。我们只不需要把重心放到业务逻辑上。而应该不会只不过这些入参的判断耽误时间更多的时间。

怎么优雅的啊,设计java极其domain详细介绍

据项目场景来看,不需要两个domain模型,一个是用户实体,一个是地址实体.

Addressdomain追加:

Userdomain追加:

可以啦,上边是一个模型关系,用户-收货地址的关系是1-n的关系。上边的@Data是使用了一个就是lombok的工具,它自动导入了Setter和Getter等方法,用起来非常方便,感兴趣的读者是可以无法清楚再看看。

dao可以介绍

数据连接层,我们不使用了spring-data-jpa这个框架,它具体的要求我们只要不能继承框架提供的接口,并且通过约定对方法接受取名,就是可以能完成我们想要的数据库操作。

用户数据库操作不胜感激:

收货地址操作如下:

如果说读者所看见的,我们的DAO只必须能继承JpaRepository,它就早帮我们结束了都差不多的CURD等操作,假如想知道一点一些跪求spring-data的这个项目,请可以参考再看看spring的官方文档,它比不方案我们对异常的研究。

Service异样设计

ok,再一次到了我们的重点了,我们要结束service一些的部分操作:直接添加收货地址,删出收货地址,获取收货地址列表.

首先看我的service接口定义:

我们来参与看看利用:

添加收货地址

简单以后再来看下之前收拾好的约束条件:

入参:

用户id

收货地址实体信息

管理和约束:

用户id没法为空,且此用户倒是是存在的

收货地址的必要的话字段没法为空

如果没有用户还没有收货地址,当此收货地址创建家族时设置里成默认收货地址

先看以上代码利用:

其中,也完成了根据上述规定所详细解释的三点约束条件,当三点约束条件都不满足时,才可以接受都正常的业务逻辑,不然将掷下异样(象在此处建议您一抛运行时十分-RuntimeException)。

能介绍以下以上我所都用到的技术:

1、(T t)这个是建议使用Guava中的参与推测的,是因为service中应用的不验证较低,所以我我建议你将Preconfitions把它改成静态导入的

当然了Guava的github中的只能说明也个人建议我们那样建议使用。

2、(validator,address)这个使用了hibernate实现的jsr303规范来做的,必须传遍一个validator和一个是需要验正的实体,那么validator是该如何查看的呢,万分感谢:

他将资源一个Validator对象,然后再我们在service中参与吸纳便是可以可以使用了:

那么BeanValidators这个类是要如何实现程序的?不过实现很很简单,只要去可以确定jsr303的标示注解就就ok啦了。

这样jsr303的注解写哪了呢?其实是写在address实体类中了:

方法 地址 异样 问题 收货

版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。