java.lang.NullPointerException- 如何处理空指针异常

当应用程序试图null在须要对象的状况下使用时抛出。这些包括:

1 调用null对象的实例方法。 2 访问或修改null对象的字段。 3 把长度null看成一个数组。 4 像访问或修改null阵列同样访问或修改插槽。 5 投掷null就好像它是一个Throwable 价值。 6 应用程序应该抛出此类的实例来指示null对象的其余非法使用。 7 NullPointerException对象能够由虚拟机构造,就像抑制被禁用和/或堆栈跟踪不可写同样。

为何咱们须要空值?

1 如前所述,nullJava是一种特殊的值。 2 它在编码某些设计模式(如空对象模式和单例模式)时很是有用。 3 空对象模式提供了一个对象做为缺乏给定类型对象的代理。 4 Singleton模式确保只建立一个类的一个实例,而且旨在提供对象的全局访问点。


例如,最多建立一个类实例的示例方法是将其全部构造函数声明为private,而后建立一个返回该类的惟一实例的公共方法:

TestSingleton.java:java

import java.util.UUID;
class
Singleton { private static Singleton single = null; private String ID = null; private Singleton() { /* Make it private, in order to prevent the creation of new instances of * the Singleton class. */ ID = UUID.randomUUID().toString(); // Create a random ID. } public static Singleton getInstance() { if (single == null) single = new Singleton(); return single; } public String getID() { return this.ID; } } public class TestSingleton { public static void main(String[] args) { Singleton s = Singleton.getInstance(); System.out.println(s.getID()); } }

 

在这个例子中,咱们声明了一个Singleton类的静态实例。该实例在该getInstance方法内最多初始化一次。注意使用null启用惟一实例建立的值。

如何避免NullPointerException程序员

为了不这种状况NullPointerException,请确保在使用它们以前,全部对象都已正确初始化。注意,当你声明一个引用变量时,你真的建立了一个指向对象的指针。在向对象请求方法或字段以前,您必须验证指针是否为空。设计模式

另外,若是引起异常,请使用驻留在异常堆栈跟踪中的信息。执行的堆栈跟踪由JVM提供,以启用应用程序的调试。找到捕获异常的方法和行,而后肯定哪一个引用等于在特定行中为null。数组

在本节的其他部分中,咱们将介绍一些处理上述例外的技术。可是,它们并无消除这个问题,程序员在编写应用程序时应该当心。安全

1.字符串与文字的比较
应用程序执行代码中的一个很是常见的状况涉及字符串变量和文字之间的比较。文字能够是一个字符串或Enum的元素。不要从空对象调用方法,而应考虑从文字中调用它。例如,观察如下状况:框架

1 String str = null; 2 if(str.equals(“Test”)){ 3      / *这里的代码将不会被触发,由于会抛出异常。* /
4 }

上面的代码片断会抛出一个NullPointerException。可是,若是咱们从文字中调用方法,那么执行流程一般会继续:dom

1 String str = null; 2 if(“Test”.equals(str)){ 3      / *正确的用例。不会抛出异常。* /
4 }

2.检查方法的参数
在执行你本身的方法的主体以前,必定要检查它的参数为空值。只有在正确检查了参数后,才继续执行该方法。不然,您能够抛出一个IllegalArgumentException并通知调用方法传递的参数有问题。函数

例如:工具

1 public static int getLength(String s){ 2      若是(s == null3  抛出新的IllegalArgumentException(“参数不能为空”); 4 
5      return s.length(); 6 }

3.优先使用String.valueOf()方法代替toString()
当您的应用程序代码须要对象的字符串表示形式时,请避免使用该对象的toString方法。若是你的对象的引用等于null,NullPointerException则会抛出a。单元测试

相反,考虑使用静态String.valueOf方法,该方法不会抛出任何异常并打印"null",以防函数的参数等于null。

4.使用三元运算符
该ternary操做是很是有用的,能够帮助咱们避免了NullPointerException。运营商的形式是:

1 布尔表达式?value1:value2;

首先,评估布尔表达式。若是表达式为true,则返回value1,不然返回value2。咱们可使用ternary运算符来处理空指针,以下所示:

1 String message =(str == null)?"":str.substring(0,10);

若是str引用为空,则消息变量将为空。不然,若是str指向实际数据,则消息将检索它的前10个字符。

5.建立返回空集合而不是null的方法
一个很是好的技术是建立返回一个空集合的方法,而不是一个null值。你的应用程序的代码能够遍历空集合并使用它的方法和字段,而不会抛出一个NullPointerException。例如:

Example.java

 1 public class Example {  2      private static List<Integer> numbers = null;  3 
 4      public static List<Integer> getList() {  5           if (numbers == null)  6                return Collections.emptyList();  7           else
 8                return numbers;  9  } 10 }

6.使用Apache的StringUtils类
Apache的Commons Lang是一个为java.langAPI 提供帮助工具的库,好比字符串操做方法。提供字符串操做的示例类是StringUtils.java,它null静静地处理输入字符串。

你可使用StringUtils.isNotEmpty, StringUtils.IsEmpty和StringUtils.equals方法,以免NullPointerException。例如:

1 if(StringUtils.isNotEmpty(str)){ 2  System.out.println(str.toString()); 3 }

7.使用contains(),containsKey(),containsValue()方法
若是您的应用程序代码使用集合,例如Maps考虑使用包含containsKey和containsValue方法。例如,在地图中验证其存在以后,检索特定键的值:

1 Map <String,String> map = ... 2 ... 3 String key = ... 4 String value = map.get(key); 5 的System.out.println(value.toString()); //若是值为null,则会抛出异常。

在上面的代码片断中,咱们不检查密钥是否真的存在于内部Map,所以返回的值能够是null。最安全的方法以下:

1 Map <String,String> map = ... 2 ... 3 String key = ... 4 if(map.containsKey(key)){ 5      String value = map.get(key); 6      的System.out.println(value.toString()); //不会抛出异常。
7 }

8.检查外部方法的返回值
在实践中使用外部库是很常见的。这些库包含返回引用的方法。确保返回的参考不是null。另外,请考虑阅读该方法的Javadoc,以便更好地理解其功能和返回值。

9.使用断言
断言在测试代码时很是有用,而且能够被使用,以免执行代码片段,从而致使错误NullPointerException。Java断言是用assert关键字实现的,并抛出一个AssertionError。

请注意,您必须显式启用JVM的断言标志,方法是使用–ea参数执行该标志。不然,断言将被彻底忽略。

使用Java断言的示例示例以下:

1 public static int getLength(String s){ 2      / *确保String不为null。* / 
3      assert(s!= null); 4 
5      return s.length(); 6 }

若是您执行上面的代码段并传递一个空参数getLength,则会出现如下错误消息:

1 Exception in thread "main" java.lang.AssertionError

最后,您可使用测试框架Assert提供的类jUnit。

10.单元测试
在测试代​​码的功能和正确性时,单元测试可能很是有用。花一些时间编写一些测试用例,验证NullPointerException应用程序的代码是否经历了特定的执行流程,不然将引起no 。

##现有的NullPointerException安全方法

1.访问类的静态成员或方法
当你的代码试图访问静态变量或类的方法时,即便对象的引用等于null,JVM也不会抛出一个NullPointerException。这是因为Java编译器在编译过程当中将静态方法和字段存储在特殊位置。所以,静态字段和方法不与对象相关联,而与类的名称相关联。

例如,下面的代码不会抛出NullPointerException:

TestStatic.java:

 1 class SampleClass {  2 
 3      public static void printMessage(){  4  System.out.println(“Hello Java Geeks!”);  5  }  6 }  7 
 8 public class TestStatic {  9      public static void main(String [] args){ 10           SampleClass sc = null; 11  sc.printMessage(); 12  } 13 }

注意,尽管SampleClass等于的实例null将会被正确执行。可是,对于静态方法或字段,最好以静态方式访问它们,好比SampleClass.printMessage()。

2.运营商的instanceof
instanceof即便对象的引用等于,也可使用该运算符null。在instanceof操做时,参考值等于为null,不抛出一个返回false NullPointerException。例如,考虑下面的代码片断:

1 String str = null; 2 if(str instanceof String) 3      System.out.println("It's an instance of the String class!"); 4 else
5      System.out.println("Not an instance of the String class!");

正如预期的那样,执行的结果是:

1 Not an instance of the String class!

 

这是一篇关于如何处理Java的教程NullPointerException。转载

相关文章
相关标签/搜索