前言
事情的经过是这亚子的,在下发现吧,有时候看到别人的代码,看到一些很明显的问题,我都会想要提醒一下,这样写会导致什么什么的,但是事实上好像没几个人会真的用心听从人家的建议(甚至有些杠精会一直杠,这样写多方便呐、这个值不会为空哒诸如此类),这个时候我也懒得和他们争论,每个人都有自己写代码的习惯,但是一些错误的代码编写方式会导致什么问题呢。
问题一:冗余
很多时候一些功能模块会使用到一些逻辑一样的代码,这时候开发人员为了方便都会使用Ctrl+C、Ctrl+V,特别是在项目特别赶的时候,我觉得呢,不管写什么代码我都可以理解,但是我就希望写完之后有时间的话可以尝试一下优化一下代码,将这段重复的代码进行整合,减少冗余的代码,这样做的目的也是有好处的,比如说你后续要改这段冗余的代码的时候,但是这段代码在很多地方都有你copy的痕迹,这个时候你就不得不去将其他的地方也改了,有时候改漏了一个,哦豁完蛋~
我:????,用着JPA然后手撸SQL,那使用JPA的目的在哪里???而且不知道这样写维护成本异常高么,何况你这个类1000多行代码全是这样的(ps:service超可怕,当时给我吓尿惹,所有的功能都在同一个方法里面,然后疯狂嵌套),说到这里我就得插一句了,虽然你们是一次性开发(当时过来驻点,功能有了就行了)但是吧,这也不用这样乱写吧,这让后面接手的人怎么办,我重构代码的时候一度想清空代码重写,奈何代码过于复杂,看了好久都不知道逻辑是啥,最后还是放弃了。
正确的姿势是怎么样的,拿查询举例子,如果只是单表查询,那不管你的条件是什么,返回值都是一样的,这个时候我们可以写一个通用的查询方法,然后再让其他的方法去调用,这样我们查询的时候就只需要传入对应的参数即可,不用再去写一大堆sql。这样做还有一个好处就是,如果表结构变了,你改的也只是通用查询那条SQL,而不是全部的,如下图。
问题二:空指针异常(NullPointerException)
有些判断非空写了等于没写,如下图
既然都知道要判断非空了,为啥还要.size()呢,生怕不抛异常?
下面是正确判断集合的姿势
空指针问题也算是我们日常开发最容易遇到问题的地方吧,那么怎么避免空指针异常呢,可能大家都知道,无非就是判断变量、对象、集合是不是空,下面举一些比较常见的例子:
1、参数导致的空指针
问题:一个方法定义的参数是int这种基本类型,如果我们传个Null就会出问题了,这种情况往往发生在前端向后端发送请求,有些参数是可选的,默认为Null。
解决:参数定义全部使用封装类型,例如Intger、Long等这些。
2、调用空对象导致的空指针
有时候查询数据库返回的对象或者集合时,如果查询结果为空,但是我们又调用了里面的属性就会出现异常。
解决:再调用一个对象或者变量前,我们要判断非空,别说什么这个数据库查出来不可能为空的,我们写程序的不可能写出完美的无bug的代码,但是我们可以避免我们目前知道的bug。
问题三:变量命名
例:你们知道这三个变量干嘛用的吗,我也不知道,乱起名字也就算了,还等于0这不是多此一举?不知道基本类型默认值就是0么,
有时候我们为了判断某个方法返回值往往会声明一个变量去接收,为了图一方便就会随便起个aabbcc啥的,后面回头再看的时候自己都不知道这个变量干嘛的,特别是该变量用的频繁的时候,你自己跟着逻辑走的时候都不知道哪个变量是哪个方法的返回。
问题四:范型类
下面是一个登录的接口,返回值是ApiResult,这没毛病吧,然后这个ApiResult是一个范型类,前端问xxx接口的返回是什么的时候,那么作为后端就得去找对应的接口,直到看到这个接口的返回是ApiResult的时候我的内心是奔溃的,这意味着我还得去翻代码才能知道这个类型具体是某个对象还是某个基本类型,最后我翻到了Service层{>_<},啥也不说了,难受~。
反例:Controller登录接口
正确姿势:每个接口都明确标明类型,方便自己也方便他人
上面举的例子都是在下真正遇到的,就写这么多啦,懂的都懂,不懂的多看看《阿里巴巴Java开发手册(泰山版)》,上面很多写Java代码的技巧以及需要注意的地方,是一份业内公认的开发手册。