当前位置: 主页 > JAVA语言

java空指针异常处理-空指针异常的原因

发布时间:2023-02-09 07:18   浏览次数:次   作者:佚名

当应用程序尝试在需要对象的地方使用 null 时抛出。 这些包括:

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

为什么我们需要空值?

如前所述,nullJava 是一种特殊的值。 它在编写某些设计模式(例如空对象模式和单例模式)时很有用。 空对象模式提供一个对象作为给定类型对象不存在的代理。 单例模式确保只创建一个类的一个实例,旨在提供对对象的全局访问点。

例如,最多创建一个类实例的一种示例方法是将其所有构造函数声明为私有,然后创建一个返回该类唯一实例的公共方法:

测试单例.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)

空指针异常的原因_java空指针异常处理_java报错空指针异常

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,请确保所有对象在使用前都已正确初始化。 请注意,当您声明一个引用变量时,您实际上创建了一个指向该对象的指针。 在从对象请求方法或字段之前java空指针异常处理,您必须验证指针不为空。

此外,如果抛出异常,请使用驻留在异常堆栈跟踪中的信息。 执行的堆栈跟踪由 JVM 提供,以启用应用程序的调试。 找到捕获异常的方法和行,然后确定在该特定行中哪个引用等于 null。

在本节的其余部分,我们将描述一些处理上述异常的技术。 然而,它们并没有消除这个问题,程序员在编写应用程序时应该小心。

1.字符串和字面量的比较

应用程序执行代码中一个非常常见的情况涉及字符串变量和文字之间的比较。 文字可以是字符串或枚举的元素。 与其从空对象调用方法,不如考虑从文字中调用它。 例如,观察以下内容:

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

上面的代码片段将抛出 NullPointerException。 但是,如果我们从文字中调用该方法,那么执行流程通常会继续:

java报错空指针异常_java空指针异常处理_空指针异常的原因

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

2.检查方法的参数

在执行您自己的方法的主体之前,请务必检查其参数是否为空值。 只有在正确检查参数后,方法的执行才会继续。 否则,您可以抛出 IllegalArgumentException 并通知调用方法传递的参数有问题。

例如:

public static int getLength(String s){
     如果(s == null)
          抛出新的IllegalArgumentException(“参数不能为空”);
     return s.length();
}

3. 更喜欢使用 String.valueOf() 方法而不是 toString()

当您的应用程序代码需要对象的字符串表示形式时,请避免使用该对象的 toString 方法。 如果您的对象的引用等于 null,则会抛出 NullPointerException。

相反,考虑使用静态 String.valueOf 方法,如果函数的参数等于 null,它不会抛出任何异常并打印“null”。

4.使用三元运算符

三元非常有用,可以帮助我们避免 NullPointerException。 运算符的形式为:

布尔表达式?value1:value2;

首先,计算布尔表达式。 如果表达式为真,则返回值 1,否则返回值 2。 我们可以使用三元运算符来处理空指针,如下所示:

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

如果 str 引用为空java空指针异常处理,则消息变量将为空。 否则,如果 str 指向实际数据,则 message 将检索其前 10 个字符。

5. 创建返回空集合而不是 null 的方法

一种非常好的技术是创建返回空集合而不是空值的方法。 您的应用程序代码可以遍历空集合并使用其方法和字段而不会抛出 NullPointerException。 例如:

例子.java

public class Example {
     private static List numbers = null;

java报错空指针异常_空指针异常的原因_java空指针异常处理

public static List getList() { if (numbers == null) return Collections.emptyList(); else return numbers; } }

6.使用Apache的StringUtils类

Apache 的 Commons Lang 是一个为 java.lang API 提供辅助工具的库,例如字符串操作方法。 提供字符串操作的示例类是 StringUtils.java,它以静默方式处理输入字符串。

您可以使用 StringUtils.isNotEmpty、StringUtils.IsEmpty 和 StringUtils.equals 方法来避免 NullPointerException。 例如:

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

7.使用contains()、containsKey()、containsValue()方法

如果您的应用程序代码使用地图等集合,请考虑使用 containsKey 和 containsValue 方法。 例如,要在验证其在映射中的存在后检索特定键的值:

Map  map = ... 
... 
String key = ... 
String value = map.get(key); 
的System.out.println(value.toString()); //如果值为null,则会抛出异常。

在上面的代码片段中,我们没有检查键是否确实存在于内部 Map 中,因此返回值可以为 null。 最安全的方法如下:

Map  map = ... 
... 
String key = ... 

java空指针异常处理_空指针异常的原因_java报错空指针异常

if(map.containsKey(key)){ String value = map.get(key); 的System.out.println(value.toString()); //不会抛出异常。 }

8.查看外部方法的返回值

在实践中使用外部库非常普遍。 这些库包含返回引用的方法。 确保返回的引用不为空。 此外,请考虑阅读该方法的 Javadoc 以更好地理解它的作用和返回的内容。

9.使用断言

断言在测试代码时非常有用,可用于避免执行导致 NullPointerException 错误的代码片段。 Java 断言使用 assert 关键字实现并抛出 AssertionError。

请注意,您必须通过使用 --ea 参数执行它来显式启用 JVM 的断言标志。 否则,断言将被完全忽略。

使用 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。

10. 单元测试

在测试代​​码的功能和正确性时,单元测试非常有用。 花一些时间编写一些测试用例,验证 NullPointerException 应用程序的代码是否经过特定的执行流程,否则不会抛出任何异常。

## 现有的 NullPointerException 安全方法

1.访问类的静态成员或方法

当您的代码试图访问静态变量或类方法时,即使对象引用等于 null,JVM 也不会抛出 NullPointerException。 这是由于 Java 编译器在编译期间将静态方法和字段存储在特殊位置。 因此,静态字段和方法不与对象相关联,而是与类名相关联。

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

空指针异常的原因_java空指针异常处理_java报错空指针异常

测试静态.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()。

2.算子的instanceof

即使对象的引用等于 null,也可以使用 instanceof 运算符。 在instanceof操作中,引用值等于null,不会抛出false返回NullPointerException。 例如,考虑以下代码片段:

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 的教程。