`
pda158
  • 浏览: 192981 次
社区版块
存档分类
最新评论

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

阅读更多
1) 从已知的String对象中调用equals()和equalsIgnoreCase()方法,而非未知对象。
  总是从已知的非空String对象中调用equals()方法。因为equals()方法是对称的,调用a.equals(b)和调用b.equals(a)是完全相同的,这也是为什么程序员对于对象a和b这么不上心。如果调用者是空指针,这种调用可能导致一个空指针异常
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");
}
 这是避免空指针异常最简单的Java技巧,但能够导致巨大的改进,因为equals()是一个常见方法。
  2) 当valueOf()和toString()返回相同的结果时,宁愿使用前者。
  因为调用null对象的toString()会抛出空指针异常,如果我们能够使用valueOf()获得相同的值,那宁愿使用valueOf(),传递一个null给valueOf()将会返回“null”,尤其是在那些包装类,像Integer、Float、Double和BigDecimal。
  BigDecimal bd = getPrice();
  System.out.println(String.valueOf(bd)); //不会抛出空指针异常
  System.out.println(bd.toString()); //抛出 "Exception in thread "main" java.lang.NullPointerException"
  3) 使用null安全的方法和库 有很多开源库已经为您做了繁重的空指针检查工作。其中最常用的一个的是Apache commons 中的StringUtils。你可以使用StringUtils.isBlank(),isNumeric(),isWhiteSpace()以及其他的工具方法而不用担心空指针异常。
//StringUtils方法是空指针安全的,他们不会抛出空指针异常
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
 但是在做出结论之前,不要忘记阅读空指针方法的类的文档。这是另一个不需要下大功夫就能得到很大改进的Java最佳实践。4) 避免从方法中返回空指针,而是返回空collection或者空数组。
  这个Java最佳实践或技巧由Joshua Bloch在他的书Effective Java中提到。这是另外一个可以更好的使用Java编程的技巧。通过返回一个空collection或者空数组,你可以确保在调用如size(),length()的时候不会因为空指针异常崩溃。Collections类提供了方便的空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来代替空指针。
  5) 使用annotation@NotNull 和 @Nullable
  在写程序的时候你可以定义是否可为空指针。通过使用像@NotNull和@Nullable之类的annotation来声明一个方法是否是空指针安全的。现代的编译器、IDE或者工具可以读此annotation并帮你添加忘记的空指针检查,或者向你提示出不必要的乱七八糟的空指针检查。IntelliJ和findbugs已经支持了这些annotation。这些annotation同样是JSR 305的一部分,但即便IDE或工具中没有,这个annotation本身可以作为文档。看到@NotNull和@Nullable,程序员自己可以决定是否做空指针检查。顺便说一句,这个技巧对Java程序员来说相对比较新,要采用需要一段时间。
  6) 避免你的代码中不必要的自动包装和自动解包。
  且不管其他如创建临时对象的缺点,如果wrapper类对象是null,自动包装同样容易导致空指针异常。例如如果person对象没有电话号码的话会返回null,如下代码会因为空指针异常崩溃。
  Person ram = new Person("ram");
  int phone = ram.getPhone();
  当使用自动包装和自动解包的时候,不仅仅是等号,< > 同样会抛出空指针异常。你可以通过这篇文章来学习更多的Java中的自动包装和拆包的陷阱。
  7) 遵从Contract并定义合理的默认值。
  在Java中避免空指针异常的一个最好的方法是简单的定义contract并遵从它们。大部分空指针异常的出现是因为使用不完整的信息创建对象或者未提供所有的依赖项。如果你不允许创建不完整的对象并优雅地拒绝这些请求,你可以在接下来的工作者预防大量的空指针异常。类似的,如果对象允许创建,你需要给他们定义一个合理的默认值。例如一个Employee对象不能在创建的时候没有id和name,但是是否有电话号码是可选的。现在如果Employee没有电话号码,你可以返回一个默认值(例如0)来代替返回null。但是必须谨慎选择,哟有时候检查空指针比调用无效号码要方便。同样的,通过定义什么可以是null,什么不能为null,调用者可以作出明智的决定。failing fast或接受null同样是一个你需要进行选择并贯彻的,重要的设计决策
  8)定义数据库中的字段是否可为空。
  如果你在使用数据库来保存你的域名对象,如Customers,Orders 等,你需要在数据库本身定义是否为空的约束。因为数据库会从很多代码中获取数据,数据库中有是否为空的检查可以确保你的数据健全。在数据空中维护null约束同样可以帮助你减少Java代码中的空指针检查。当从数据库中加载一个对象是你会明确,哪些字段是可以为null的,而哪些不能,这可以使你代码中不必要的!= null检查最少化。
  9) 使用空对象模式(Null Object Pattern)
  还有一种方法来避免Java中的空指针异常。如果一个方法返回对象,在调用者中执行一些操作,例如Collection.iterator()方法返回迭代器,其调用者执行遍历。假设如果一个调用者并没有任何迭代器,其可以返回空对象(Null object)而非null。空对象是一个特殊的对象,其在不同的上下文中有不同的意义。例如一个空的迭代器调用hasNext()返回false时,可以是一个空对象。同样的在返回Container和Collection类型方法的例子中,空对象可以被用来代替null作为返回值。
10
6
分享到:
评论
3 楼 lui0101 2015-03-31  
自动包装同样容易导致空指针异常。

这不对吧,应该是自动解包(自动拆箱吧)
2 楼 一生爱你 2014-11-24  
不错。学习了
1 楼 kidneyball 2014-10-23  
不错,建议加入Java8和Guava的Optional方案

相关推荐

    Java8里面lambda的最佳实践Java开发Java经

    以上内容涵盖了Java 8 Lambda的最佳实践,通过熟练掌握这些技巧,可以提升Java开发的效率和代码质量。在实际开发中,结合Java 8的新特性,如Stream API和Optional类,可以使代码更加简洁、高效。

    Java实际开发中的小技巧汇总

    通过阅读源码,你可以了解到最佳实践和设计模式,同时也能解决实际开发中遇到的问题。 8. **工具使用**:IDEA、Eclipse等集成开发环境的熟练使用可以极大地提高开发效率。例如,快捷键操作、代码自动完成、重构功能...

    Java中有关Null的9件事Java开发Java经验技巧

    在Java编程语言中,`null`是一个特殊值,表示...了解并熟练应用这些知识点能显著提高Java代码的健壮性和可靠性,避免因`null`引起的运行时错误。对于Java开发者来说,理解和处理`null`是日常开发中不可或缺的一部分。

    Java程序设计技巧1001例.rar

    在Java编程世界中,设计技巧是提升代码质量、可维护性和效率的关键因素。"Java程序设计技巧1001例"这个压缩包文件显然是一部针对初学者的实用指南,旨在...在实践中不断学习和磨练,将使你成为一名出色的Java开发者。

    一本介绍如何将现有的 Java 代码重构为 Kotlin 代码的书籍

    书中不仅提供了丰富的重构技巧,还包括了实用的示例和最佳实践,旨在帮助开发者更高效地完成代码转换,并提升重构后代码的质量和性能。 #### 二、重构技巧与方法 **1. 语法转换** - **基础语法差异**:Kotlin在很...

    Java Tips

    【Java Tips】这篇博客主要探讨了Java编程中的实用技巧和最佳实践,旨在帮助开发者提高代码质量和效率。在Java开发过程中,理解和掌握这些技巧是至关重要的,因为它们可以帮助我们避免常见错误,优化性能,并且使...

    浅析JAVA编程中异常处理的方法与技巧.zip

    本文将深入探讨Java异常处理的基本概念、方法以及一些实用技巧,帮助开发者更好地理解和应用这一核心特性。 异常是程序运行过程中遇到的非正常情况,可能是由于逻辑错误、资源问题或外部条件不满足等导致的。Java...

    Java安全性编程指南(PDG)

    通过深入学习和实践《Java安全性编程指南(PDG)》中的原则和技巧,开发者能够构建更健壮、更安全的Java应用程序,为用户提供一个可信的执行环境。这不仅有助于保护用户的隐私,也有助于维护企业的声誉和合规性。

    JAVA.BUG模式详解

    在Java编程中,"BUG模式"通常指的是程序员在...定期审查代码、进行性能分析以及持续学习Java最佳实践,都是优化编程不可或缺的部分。《JAVA.BUG模式详解》这本书将深入讲解这些主题,帮助你成为更出色的Java程序员。

    JAVA异常出错的教程,非常全面。

    在这个全面的教程中,我们将深入探讨Java异常的基本概念、分类、处理机制以及最佳实践。 首先,Java异常是程序运行时发生的错误,它中断了正常的执行流程。Java通过一个异常类层次结构来表示各种类型的错误,这些...

    JAVA错误收集

    10. **异常的最佳实践**:避免在catch块中只写“return”或“pass”,应该提供足够的信息帮助追踪问题,比如记录异常信息或重新抛出。 理解并熟练应用这些知识点,将有助于Java开发者更有效地诊断和解决运行时问题...

    java 常用代码

    这篇博客“java 常用代码”可能涵盖了Java编程中的常见代码片段、实用技巧和最佳实践。由于没有直接提供博客的具体内容,我将根据Java的一般知识和常用编程实践来详细解释一些关键知识点。 1. **基础语法**:Java的...

    Thinking in Java第三版+第四版(中文版+习题答案)

    2. 第四版在第三版的基础上增加了更多实际编程技巧和最佳实践,使得内容更加贴近现代Java开发的需求。 关于Java编程的知识点: 1. **基础语法**:包括变量、数据类型、运算符、流程控制(if语句、switch、循环)、...

    Safe-Programming-for-JAVA.rar_java programming

    Java是一种广泛使用的面向对象的编程语言,以...以上所述只是"Safe Programming for JAVA.rar"可能涵盖的部分内容,实际的PDF文档可能会提供更详细的实例、最佳实践和技巧,帮助开发者编写出更安全、更高效的Java代码。

    Java异常处理

    Java异常处理是Java编程语言中的一个关键特性,它允许程序员优雅地处理程序运行时可能...通过合理地使用`try-catch-finally`,以及正确地处理`checked`和`unchecked`异常,开发者可以编写出更加安全、可靠的Java应用。

    异常捕获-master.zip项目安卓应用源码下载

    在Android应用开发中,异常处理是一项至关重要的任务,它确保了程序在遇到错误或意外情况时能够优雅地恢复,或者至少提供有用的错误信息...无论是学生还是开发者,都应该深入研究这个项目,掌握其中的技巧和最佳实践。

    java高效编程.pdf

    Java高效编程涵盖了许多关键实践和策略,以提升代码性能、减少资源消耗并增强代码的可维护性。以下是一些从给定内容中提取的核心知识点: 1. **字符串连接**: ...在实际开发中,这些技巧应该被广泛采用和应用。

    java异常总结

    #### 七、最佳实践 - **使用具体异常**:尽量使用具体的异常类型而不是使用通用的异常类型,这有助于提高异常处理的针对性。 - **避免过度使用异常**:异常应该是用来处理异常情况而不是正常的控制流程。 - **合理...

Global site tag (gtag.js) - Google Analytics