避免Java中NullPointerException的Java技巧和最佳实践

Java中的NullPointerException是咱们最常常遇到的异常了,那咱们到底应该如何在编写代码是防患于未然呢。下面咱们就从几个方面来入手,解决这个棘手的​问题吧。​java

值得庆幸的是,经过应用一些防护性编码技术并遵循应用程序多个部分之间的约定,您能够在必定程度上避免Java中的NullPointerException。程序员

顺便说一下,在本文中,咱们将学习一些Java的编码技术和最佳实践,这些技巧和最佳实践可用于避免的Java中的空指针异常。遵循这些Java的技巧还能够最大程度地减小不少Java代码中的 x !=NULL 检查。面试

做为经验丰富的Java的程序员,您可能已经知道其中一些技巧,而且已经在项目中遵循了这些技巧,可是对于新手和中级 发人员来讲,这多是个不错的学习机会。顺便说一句,若是您知道其余避免Java中的NullPointerException并减小的Java中的空检查的Java的技巧,请与咱们分享。算法

Java技巧和最佳实践

这些都是简单的技术,很容易遵循,可是对代码质量和健壮性有重大影响。以个人经验,仅第一个技巧就能够显着提升代码质量。如前所述,若是您知道任何其余Java技巧或最佳实践,能够帮助减小空检查,那么能够经过评论本文与咱们分享。数据库

1)在已知的字符串而不是未知的对象上调用equals()和equalsIgnoreCase()方法

始终在不为null的已知字符串上调用equals()方法。因为equals()方法的方法是对称的,调用a.equals(b)与调用b.equals(a)是同样的,这就是为何不少程序员不注意对象a和b。若是调用者为空,则此调用的一个反作用就是可能致使NullPointerException。编程

Object unknownObject = null;

//错误的方式 - 可能引发NullPointerException
if(unknownObject.equals("knownObject")){
   System.err.println("This may result in NullPointerException if unknownObject is null");
}

//正确的方式 - 若是unknownObject为null避免 NullPointerException
if("knownObject".equals(unknownObject)){
    System.err.println("better coding avoided NullPointerException");
}

这是避免NullPointerException的最简单的Java技巧或最佳实践,可是因为equals()是一种常见方法,所以带来了极大的改进 。数组

2)优先使用valueOf()而不是toString(),两个都返回相同的结果

因为在 null对象上调用toString()会引起NullPointerException ,所以,若是咱们能够经过调用valueOf()得到相同的值, 则最好这样作,由于将null传递给valueOf()会返回“ null ”,特别是在诸如Integer ,Float ,Double 这样的包装类的状况下或BigDecimal 。安全

BigDecimal bd = getPrice();
System.out.println(String.valueOf(bd)); /不会抛出NPE
System.out.println(bd.toString()); //在main线程抛出java.lang.NullPointerException"异常

若是不肯定对象是否为null,请遵循此Java技巧。ide

三、使用null安全的方法和库

有不少这样开源库,这些库为您检查空作了大量工做。最多见的一种来自Apache Common 的StringUtils。您可使用StringUtils.isBlank() ,ISNUMERIC() ,isWhiteSpace()和其余实用程序方法,而没必要担忧NullPointerException 。工具

//StringUtils中的方法是空指针安全的, 它不会出现NullPointerException
System.out.println(StringUtils.isEmpty(null));
System.out.println(StringUtils.isBlank(null));
System.out.println(StringUtils.isNumeric(null));
System.out.println(StringUtils.isAllUpperCase(null));

输出结果:

true
true
false
false

可是,在使用库方法以前,请不要忘记阅读Null安全方法和类的文档。这是另外一种Java最佳实践,不须要太多的时间,但能够带来很大的改进。

四、避免从方法中返回null,而应返回空集合或空数组

Joshua Bloch在他的书《Effective Java》中也提到了Java最佳实践或技巧,从这本书中你将得到更多的Java编程技巧。在公众号【Java知己】,后台回复:Effective Java,能够得到该书籍的连接。

经过返回空集合或空数组,您能够确保基本调用(如size(),length())不会因NullPointerException异常而失败。集合类提供方便的空的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_SET 和Collections.EMPTY_MAP 而不是返回null。

五、使用注释@NotNull和@Nullable

在编写方法时,能够经过使用@NotNull 和@Nullable 这样的注释来声明方法是否为null安全,从而定义有关可空性的契约。 现代的编译器,IDE或工具能够读取此批注并帮助您进行缺失的空检查,或者能够通知您没必要要的空检查,这会使您的代码混乱。

IntelliJ IDE 和FindBugs的已经支持这种注释。这些注释也是JSR 305的一部分,可是即便在没有任何工具或IDE支持的状况下,此注释自己也能够做为文档使用。经过查看 @NotNull 和@Nullable ,程序员本身能够决定是否检查null。顺便说一句,对于Java程序员来讲,这是相对较新的最佳实践,要花些时间才能被利用起来。

六、避免在代码中预先的自动装箱和拆箱

尽管存在其余缺点,例如建立临时对象,但若是包装类对象为null,则自动装箱也容易发生NullPointerException 。例如, 若是人员没有电话号码,则如下代码将失败,会NullPointerException ,而不是返回null 。

Person ram = new Person("ram");
int phone = ram.getPhone();

若是与自动装箱和拆箱一块儿使用,既也会引起NullPointerException 。

七、遵照约定并定义合理的预设值

在Java的中避免NullPointerException异常的最佳方法之一就是定义初始值并遵循约定。大多数NullPointerException异常发生的缘由是使用不完整的信息建立对象或未提供全部必需的依赖关系。若是您不容许建立不完整的对象并优雅地拒绝任何此类请求,则能够防止不少NullPointerException 的出现。一样,若是 容许建立对象,则应该使用合理的替代值。例如,若是没有id 和name ,则不能建立Employee 对象 ,可是能够具备可选的电话号码。如今,若是员工没有电话号码而不是返回零,不然返回默认值,例如零,可是必须谨慎地选择该选项,踩在某些时候检查null很容易,而不是拨打无效号码。一个相同的注释,经过定义什么能够为空和什么不能为空,调用者能够作出明智的决定。选择fast-fail仍是接受null也是您须要采起并坚持一致的重要设计方法。

八、若是您使用数据库来存储

客户,订单等领域对象,则应在数据库自己上定义空值约束。因为数据库能够从多个来源获取数据,所以在DB中进行空能力检查将确保数据完整性。保持数据库的空约束也将有助于减小_Java代码中的空检查_。从数据库加载对象时,您将肯定其中一部分能够为null以及其中部分不为null,这将最大程度地减小代码中的的 !=null 检查。

九、使用空对象模式

这是避免Java中的NullPointerExcpetion的另外一种方法。若是某个方法返回一个对象,该对象将在调用方上执行,例如Collection.iterator()方法返回Iterator,则调用方将在该迭代器上执行遍历。假设调用者没有任何继承器,则能够返回Null对象而不是null。Null对象是一个特殊的对象,在不一样的其中中具备不一样的含义,例如,在此处,调用hasNext()并返回false 的空Iterator 能够是null对象。相似地,对于返回容器或集合类型的方法,应使用空对象而不是返回null。我打算写一篇关于空对象模式,在这里我将分享Java中空对象的更多示例。

伙计们,这些都是容易理解的Java技巧和最佳实践,能够避免NullPointerException。您将不费吹灰之力就能够知道这些技巧有多有用。若是您要使用其余任何技巧来避免此例外(不在此列表中) ),则请经过评论与咱们分享,我将在此处后续更新。


“不积跬步,无以致千里”,但愿将来的你能:有梦为马 随处可栖!加油,少年!

关注公众号:「Java 知己」,天天更新Java知识哦,期待你的到来!

  • 发送「Group」,与 10 万程序员一块儿进步。
  • 发送「面试」,领取BATJ面试资料、面试视频攻略。
  • 发送「玩转算法」,领取《玩转算法》系列视频教程。
  • 千万不要发送「1024」...

每日福利

相关文章
相关标签/搜索