纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术 → 详解Java中NullPointerException异常的原因详解以及解决办法

详解Java中NullPointerException异常的原因详解以及解决办法

Allen Chou   2020-08-06 我要评论

本文着重讲解了详解Java中NullPointerException异常的原因详解以及解决办法。文中通过代码实例讲解的非常细致对大家的工作和学习具有一定的参考学习价值需要的朋友们下面随着小编来一起学习学习吧

NullPointerException是当您尝试使用指向内存中空位置的引用(null)时发生的异常就好像它引用了一个对象一样。

当我们声明引用变量(即对象)时实际上是在创建指向对象的指针。考虑以下代码您可以在其中声明基本类型的整型变量x:

int x;
x = 10;

在此示例中变量x是一个整型变量Java将为您初始化为0。当您在第二行中将其分配给10时值10将被写入x指向的内存中。

但是当您尝试声明引用类型时会发生不同的事情。请使用以下代码:

Integer num;
num = new Integer(10);

第一行声明了一个名为的变量num但它不包含原始值。相反它包含一个指针(因为类型Integer是一个引用类型)。既然你还没有说什么指向Java它将它设置为null意思是“ 我什么都没有指向”。

在第二行中new关键字用于实例化(或创建)Integer类型的对象并为指针变量num分配此对象。您现在可以使用解引用运算符.(点)来引用对象。

在当你声明了一个变量但是没有创建一个对象会发生Exception。如果您在创建num对象之前尝试取消引用则会得到一个NullPointerException。在最琐碎的情况下编译器将捕获问题并让您知道“num可能尚未初始化”但有时您编写的代码不会直接创建对象。

例如您可能使用了如下的方法:

public void doSomething(SomeObject obj) {
  //do something to obj
}

在这种情况下您没有创建对象obj而是假设它是在doSomething调用方法之前创建的。如果你像这样调用方法:

doSomething(null);

在这种情况下obj为null。如果该方法旨在对传入的对象执行某些操作则需要抛出异常因为NullPointerException它是程序错误程序员将需要该信息用于调试的目的。

或者可能存在这样的情况:该方法的目的不仅仅是对传入的对象进行操作因此可以接受空参数。在这种情况下您需要检查null参数并采取不同的行为。您还应该在文档中解释这一点。例如doSomething应该最好写成:

/**
 * @param obj An optional foo for ____. May be null, in which case 
 * the result will be ____.
 */
public void doSomething(SomeObject obj) {
  if(obj != null) {
    //do something
  } else {
    //do something else
  }
}

我如何解决它?

所以你有一个NullPointerException。应该如何解决?让我们举一个简单的例子它抛出NullPointerException:

public class Printer {
  private String name;
 
  public void setName(String name) {
    this.name = name;
  }
 
  public void print() {
    printString(name);
  }
 
  private void printString(String s) {
    System.out.println(s + " (" + s.length() + ")");
  }
 
  public static void main(String[] args) {
    Printer printer = new Printer();
    printer.print();
  }
}

标识空值

第一步是确切地确定导致异常的值。为此我们需要做一些调试。学习阅读堆栈跟踪很重要。这将显示抛出异常的位置:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

在这里我们看到在第13行抛出异常(在printString方法中)。查看该行并通过添加日志记录语句或使用调试器来检查哪些值为空。我们发现它s是null并且调用length方法会抛出异常。我们可以看到程序在s.length()方法中删除时停止抛出异常。

追踪这些值来自哪里

接下来检查此值的来源。按照该方法的调用者我们可以看到s与传递printString(name)的print()方法并this.name为空。

跟踪应设置这些值的位置

在哪里this.name设置?在setName(String)方法中。通过一些更多的调试我们可以看到根本没有调用此方法。如果调用该方法请确保检查调用这些方法的顺序并且在print方法之后不调用set 方法。

这足以为我们提供一个解决方案:在调用printer.setName()之前添加调用printer.print()。

其他修正

该变量可以具有默认值(并且setName可以防止将其设置为null):

private String name = "";

任一print或printString方法可以检查空例如:

printString((name == null) ? "" : name);

或者您可以设计如下所示的类以便name 始终具有非null值:

public class Printer {
  private final String name;
 
  public Printer(String name) {
    this.name = Objects.requireNonNull(name);
  }
 
  public void print() {
    printString(name);
  }
 
  private void printString(String s) {
    System.out.println(s + " (" + s.length() + ")");
  }
 
  public static void main(String[] args) {
    Printer printer = new Printer("123");
    printer.print();
  }
}


相关文章

猜您喜欢

网友评论

Copyright 2020 www.SiJiMeiShi.com 【四季软件园】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式