当应用程序试图null在需要对象的情况下使用时抛出。这些包括:
调用null对象的实例方法。 访问或修改null对象的字段。 把长度null当作一个数组。 像访问或修改null阵列一样访问或修改插槽。 投掷null就好像它是一个Throwable 价值。 应用程序应该抛出此类的实例来指示null对象的其他非法使用。 NullPointerException对象可以由虚拟机构造,就像抑制被禁用和/或堆栈跟踪不可写一样。
为什么我们需要空值?
如前所述,nullJava是一种特殊的值。 它在编码某些设计模式(如空对象模式和单例模式)时非常有用。 空对象模式提供了一个对象作为缺少给定类型对象的代理。 Singleton模式确保只创建一个类的一个实例,并且旨在提供对象的全局访问点。
例如,最多创建一个类实例的示例方法是将其所有构造函数声明为private,然后创建一个返回该类的唯一实例的公共方法:
TestSingleton.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。
在本节的其余部分中,我们将介绍一些处理上述例外的技术。但是,它们并没有消除这个问题,程序员在编写应用程序时应该小心。
String str = null; if(str.equals(“Test”)){ / *这里的代码将不会被触发,因为会抛出异常。* / }
上面的代码片段会抛出一个NullPointerException。但是,如果我们从文字中调用方法,那么执行流程通常会继续:
String str = null; if(“Test”.equals(str)){ / *正确的用例。不会抛出异常。* / }
例如:
public static int getLength(String s){ 如果(s == null) 抛出新的IllegalArgumentException(“参数不能为空”); return s.length(); }
相反,考虑使用静态String.valueOf方法,该方法不会抛出任何异常并打印”null”,以防函数的参数等于null。
布尔表达式?value1:value2;
首先,评估布尔表达式。如果表达式为true,则返回value1,否则返回value2。我们可以使用ternary运算符来处理空指针,如下所示:
String message =(str == null)?"":str.substring(0,10);
如果str引用为空,则消息变量将为空。否则,如果str指向实际数据,则消息将检索它的前10个字符。
Example.java
public class Example { private static List
numbers = null; public static List
getList() { if (numbers == null) return Collections.emptyList(); else return numbers; } }
你可以使用StringUtils.isNotEmpty, StringUtils.IsEmpty和StringUtils.equals方法,以避免NullPointerException。例如:
if(StringUtils.isNotEmpty(str)){ System.out.println(str.toString()); }
Map
map = ... ... String key = ... String value = map.get(key); 的System.out.println(value.toString()); //如果值为null,则会抛出异常。
在上面的代码片段中,我们不检查密钥是否真的存在于内部Map,因此返回的值可以是null。最安全的方法如下:
Map
map = ... ... String key = ... if(map.containsKey(key)){ String value = map.get(key); 的System.out.println(value.toString()); //不会抛出异常。 }
请注意,您必须显式启用JVM的断言标志,方法是使用–ea参数执行该标志。否则,断言将被完全忽略。
使用Java断言的示例示例如下:
public static int getLength(String s){ / *确保String不为null。* / assert(s!= null); return s.length(); }
如果您执行上面的代码段并传递一个空参数getLength,则会出现以下错误消息:
Exception in thread "main" java.lang.AssertionError
最后,您可以使用测试框架Assert提供的类jUnit。
现有的NullPointerException安全方法
例如,下面的代码不会抛出NullPointerException:
TestStatic.java:
class SampleClass { public static void printMessage(){ System.out.println(“Hello Java Geeks!”); } } public class TestStatic { public static void main(String [] args){ SampleClass sc = null; sc.printMessage(); } }
注意,尽管SampleClass等于的实例null将会被正确执行。但是,对于静态方法或字段,最好以静态方式访问它们,比如SampleClass.printMessage()。
String str = null; if(str instanceof String) System.out.println("It's an instance of the String class!"); else System.out.println("Not an instance of the String class!");
正如预期的那样,执行的结果是:
Not an instance of the String class!
这是一篇关于如何处理Java的教程NullPointerException。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/209395.html原文链接:https://javaforall.net
