由@NotNull注解引出的关于Java空指针的控制

Java 小技巧和在java应用避免NullPonintException的最佳方法

在java应用程序中,一个NullPonintException(空指针异常)是最好解决(问题)的方法。同时,空指针也是写健壮的顺畅运行的代码的关键。“预防好过治疗”这句话也同样适用于令人不爽的NullPonintException。通过应用防御性的编码技术和在遵守多个部分之间的约定,你可以再很大程度上避免NullPointException。下面的这些java小技巧可以最小化像!=null这种检查的代码。作为经验丰富的java程序猿,你可能意识到这些技术的某部分项目当中使用它。但是对于大学一年级学生和中级开发者,这是一个很好的学习机会。

这是一些很容易学会的简单技术,但是对于代码质量和健壮性来说确实很重要。以我的经验,仅是第一个小技巧就已经对改进代码质量具有很大的作用了。

1)在已经的String(字符串)调用 equal()和 equalsingnoreCase()而不是未知的对象

通常在已经的非空字符串在调用equals()。因为equal()方法是对称的,调用a.equal()是同等于调用b.equal(),和这就是为什么很多部注意对象a和b,如果空的一边被调用会到导致空指针。

Object unknownObject = null;

//wrong way - may cause NullPointerException
if(unknownObject.equals("knownObject")){
  System.err.println("This may result in NullPointerException if unknownObject is null");
}
//right way - avoid NullPointerException even if unknownObject is null
if("knownObject".equals(unknownObject)){
  System.err.println("better coding avoided NullPointerException");
}

这是最重要的避免NullPointException的java技巧,但是结果会是极大的改进,因为equal()是一个很普遍的方法。

2)在两者返回相同结果的时候偏向使用valueOf()而非toString()

因为空对象调用toString()时会抛出NullPointException。如果我们可以通过调用value()得到相同的值的话,就应该使用valueOf()。这样会传递会一个空值。特别是在像Integer,Float,Double或者BigDecimla之类的包装类的情况下。

BigDecimal bd = getPrice();
System.out.println(String.valueOf(bd)); //doesn't throw NPE
System.out.println(bd.toString()); //throws "Exception in thread "main" java.lang.NullPointerException"

如果你不确定你所使用的对象是否是空的时候,请使用这个JAVA技巧

3)使用空安全方法(null safe method)或者类库

现在有很多已经为你做了null检查的开源组件出现。其中一个最为普遍的就是Apache的StringUtils。你可以使用StringUtils.isBlank(),isNumberic(),isWhiteSpace()和其他工具一些不用担心NullPointException方法。

System.out.println(StringUtils.isEmpty(null));
System.out.println(StringUtils.isBlank(null));
System.out.println(StringUtils.isNumeric(null));
System.out.println(StringUtils.isAllUpperCase(null));

Output:
true
true
false
false

但在作出任何结论之前,不要忘记阅读关于Null安全方法和类的文档。这是另一个java最佳操练,这不会要求你付出非常多的努力,但会让你获得很大的进步。

4)避免用返回空的collection或者空的array来代替从方法中返回Null

这个java技巧也是在Joshua Bloch的《Effective Java》所提及的。这本书也是一个提高JAVA编码能力的一个来源。通过返回一个空的collection或者一个空的array可以确定像size(),length()这种基础的调用不会抛出NullPointException。Collection类能够提供方便的空的List,Set和Map,(这些)有Collections.EMPTY_LIST, Collections.EMPTY_SET和 Collections.EMPTY_MAP这些能够被使用的(静态变量)。

代码如下;

 public List getOrders(Customer customer){
  List result = Collections.EMPTY_LIST;
return result;
} 

类似地你可以使用Collections.EMPTY_LIST, Collections.EMPTY_SET和 Collections.EMPTY_MAP来代替返回Null。

5)使用@NotNull和@Nullable注释

当写你可以定义关于约定可空性(Nullability),要通过使用像@NotNull和@Nullable类似的注释提示这个方法是否为空安全(null safe)。现代的编译器,IDE和其他工具可以读出这个注释来帮你做一个空检查或者告诉你是否需要空检查。IntelliJIDE和findbugs 已经支持这种注释。这些注释也是JSR 305(译者注:可以理解为java的标准)的一部分。通过看到@NotNull和@Nullable,程序猿可以自己决定是否去进行空检查。顺便说下,对于JAVA程序猿来说,这是新的最好的实践,尽管需要一点时间去适应。

6)遵循约定和定义合理的默认值

在java领域,一个最佳的避免空指针的方法之一就是和定下约定和遵守约定。大部分的NullPointException发生原因就是使用了一个不完整的信息或者并没有被提供所有的依赖信息来创建对象。如果你不允许创建不完整的对象和否定任何这种要求,你可以预防很多一段时间之后发生的NullPointException。如果对象被允许创建,那么你应该设定合理的默认值。例如,一个Employee(雇员)对象不可以在没有Id和Name属性的情况下被创建,但可以有一个可供选择的pghone number(电话号码)。如果Employee没有phone number,那么就用返回一个0来代替返回一个空值。但是这种处理必须非常小心地处理对空值的检查而不是检查非法输入。同样要注意,定义可以使空值的或者不可以空值的时候,提醒调用者作出被告知的决定。失败之后的选择或者接受空值也是一个你需要重视的重要设计。

7)如果你使用数据库去存储你的域对象(demain object)
例如:Customer、Orders等等,那么你应该定义一些在数据库对空值的约束。因为数据库可以要求获得从多个来源来的数据,在数据库中拥有对空值的检查将会确保数据的完整性。在数据库中保留对空值约束的约束也是会让你减少在JAVA中减少空检查的代码。当从数据库中取出一个对象是,你可以确保那些属性可以是空而那些属性不可以使空,这将会让那些空检查的代码最小化。

8)使用空对象模式

这是另外一个在JAVA里面避免NullPointException的方法。如果一个方法返回一个对象,哪个调用者要遍历这个对象,哪个调用者就要使用一些类似Collection.iterator()的方法去返回iterator。如果调用者没有任何的上述的这些方法,那么有可能返回的是空对象而不是空(null)。空对象是一个特别的对象,它在不同的上下文中有不同的含义。像这些返回Contrainter或者Conllection类型的方法的情况中,里面为空的对象(Empty object)应该被使用而不是返回空。

(0)

相关推荐

  • 由@NotNull注解引出的关于Java空指针的控制

    Java 小技巧和在java应用避免NullPonintException的最佳方法 在java应用程序中,一个NullPonintException(空指针异常)是最好解决(问题)的方法.同时,空指针也是写健壮的顺畅运行的代码的关键."预防好过治疗"这句话也同样适用于令人不爽的NullPonintException.通过应用防御性的编码技术和在遵守多个部分之间的约定,你可以再很大程度上避免NullPointException.下面的这些java小技巧可以最小化像!=null这种检查的

  • Java8新特性之类型注解_动力节点Java学院整理

    注解从java5开始加入这一特性,发展到现在已然是遍地开花,在很多框架中得到了广泛的使用,用来简化程序中的配置.那充满争议的类型注解究竟是什么?复杂还是便捷? 什么是类型注解 在java 8之前,注解只能是在声明的地方所使用,比如类,方法,属性:java 8里面,注解可以应用在任何地方,比如: 创建类实例 new @Interned MyObject(); 类型映射 myString = (@NonNull String) str; implements 语句中 class Unmodif

  • Java访问权限控制的重要性深入讲解

    前言 人在什么面前最容易失去抵抗力? 美色,算是一个,比如说西施的贡献薄就是忍辱负重.以身报国.助越灭吴:金钱,算是另外一个,我们古人常说"钱乃身外之物,生不带来死不带去",但我们又都知道"有钱能使鬼推磨". 除去美色和金钱,我认为还有一个,就是读者的认可--"二哥,你的文章真的很棒,我特别喜欢.希望能多多更新Java基础知识,真的是受益良多,就好像是在读王小波的散文,但又学了编程!"--你说,收到读者这样暖暖的评语,还需要美色和金钱?"

  • java实现时间控制的几种方案

    前言:最近小王同学又遇到了一个需求:线上的业务运行了一段时间,后来随着使用人数增多,出现了一个问题是这样的,一个订单会重复创建几次,导致数据库里出现了很多垃圾数据.在测试同学的不断测试下,发现问题出在了前端的一个提交按钮上,有的用户比较"着急",提交订单时候,一下子快速的点了5.6次(这手速没有几年是练不出来的,咳咳),导致请求一下子都涌进来,后端进行了重复处理.项目经理让小王优化这个点,绝对不能创建多次.还有一个需求是这样的,在与第三方对接过程中,对方提供了token进行时效性验证,

  • Java使用Condition控制线程通信的方法实例详解

    本文实例讲述了Java使用Condition控制线程通信的方法.分享给大家供大家参考,具体如下: 一 点睛 当使用Lock对象来保证同步时,Java提供了一个Condition类来保持协调,使用Condition可以让那些已经得到Lock对象.却无法继续执行的线程释放Lock对象,Condtion对象也可以唤醒其他处于等待的线程. Condition 将同步监视锁方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与Lock对象组合使用,为每个对象提供多

  • java通过方向键控制小球移动的小游戏

    本文需求实现了java通过方向键控制小球移动的具体过程,供大家参考,具体内容如下 需求分析: 第一 要画出一个小球 第二 要能通过控制方向键控制它的移动 第一部分的实现 1.首先要画一个大窗体 public class BallMove extends JFrame 在开发Java应用程序时,通常情况下利用JFrame创建大窗口.利用JFrame创建的窗口分别包含一个标题.最小化按钮.最大化按钮和关闭按钮 用主类去继承JFrame类就可以使用它的方法啦 2.接着用一个类来继承JPanel 如果说

  • Java程序流程控制:判断结构、选择结构、循环结构原理与用法实例分析

    本文实例讲述了Java程序流程控制:判断结构.选择结构.循环结构原理与用法.分享给大家供大家参考,具体如下: 本文内容: 判断结构 if 选择结构 switch 循环结构 while do-while for for each break.continue return 首发时间:2017-06-22 21:34 修改时间: 2018-03-16 17:01 判断结构: java中使用if作为判断结构 if语句有三种格式: package study.program_struct; import

  • 快速校验实体类时,@Valid,@Validated,@NotNull注解无效的解决

    目录 校验实体类参数内容不能为空时使用注解校验无效 使用@valid注解首先引入依赖 1.更换方法入参类型 2.错误内容过多 3.使用对象接收错误内容,按自己要求输出 springboot 校验机制 @Validated @Valid 1.探究原因 2.使用@Validated 实现校验机制 3.使用@Valid 实现校验机制 校验实体类参数内容不能为空时使用注解校验无效 使用@valid注解首先引入依赖 如果是SpringBoot项目,引入web开发包,就不需要再单独引入@valid依赖了.因

  • spring mvc常用注解_动力节点Java学院整理

    Spring从2.5版本开始在编程中引入注解,用户可以使用@RequestMapping, @RequestParam, @ModelAttribute等等这样类似的注解.到目前为止,Spring的版本虽然发生了很大的变化,但注解的特性却是一直延续下来,并不断扩展,让广大的开发人员的双手变的更轻松起来,这都离不开Annotation的强大作用,今天我们就一起来看看Spring MVC 4中常用的那些注解吧. 1. @Controller Controller控制器是通过服务接口定义的提供访问应用

  • 理解Java访问权限控制

    今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下为何需要访问权限控制.考虑两个场景: 场景1:工程师A编写了一个类ClassA,但是工程师A并不希望ClassA被该应用中其他所用的类都访问到,那么该如何处理? 场景2:如果工程师A编写了一个类ClassA,其中有两个方法fun1.fun2,工程师只想让fun1对外可见,也就是说,如果别的工程师来调用ClassA,只可以调用方法fun1,那么该怎么处理? 此时,访问权限控制便可以起到作用了. 在Java中,提

随机推荐