什么是空指针异常,我该如何修复它?

209

什么是空指针异常(java.lang.NullPointerException)以及它的产生原因?

有哪些方法/工具可以用来确定它的原因,以便防止该异常导致程序过早终止?

12个回答

4186
Java中有两种变量类型: 1. 基本类型:存储数据的变量。如果要操作基本变量中的数据,可以直接操纵该变量。按照惯例,基本类型始于小写字母。例如,类型为int或char的变量是基本类型。 2. 引用类型:存储对象内存地址的变量,即引用一个对象的变量。如果要操作引用变量所引用的对象,则必须取消引用。取消引用通常涉及使用“.”访问方法或字段,或使用“[”索引数组。按照惯例,引用类型通常以大写字母开头的类型表示。例如,类型为Object的变量是引用类型。
考虑以下代码,在其中声明一个未初始化的基本类型int变量:
int x;
int y = x + x;

这两行代码会导致程序崩溃,因为没有为x指定值,但我们试图使用x的值来指定y。所有的基本数据类型在操作之前都必须初始化为可用的值。

现在,有一点很有趣。引用变量可以被设置为null,这意味着“我没有引用任何东西”。你可以通过显式设置或者引用变量未初始化且编译器没有捕获到(Java会自动将变量设置为null)来得到null值。

如果引用变量被明确或因Java自动设置为null,并且你试图对其进行取消引用,那么你就会得到一个NullPointerException

NullPointerException(NPE)通常发生在你声明一个变量但在尝试使用该变量的内容之前没有创建对象并将其赋值给该变量时。所以你有一个对不存在的东西的引用。

看下面的代码:

Integer num;
num = new Integer(10);

第一行声明了一个名为num的变量,但它实际上还没有包含任何引用值。由于您尚未指定要指向什么,Java将其设置为null

在第二行中,使用new关键字来实例化(或创建)类型为Integer的对象,并将引用变量num分配给该Integer对象。

如果在创建对象之前尝试解引用num,则会出现NullPointerException。在最简单的情况下,编译器会捕获此问题并让您知道“num可能尚未初始化”,但有时您可能会编写不直接创建对象的代码。

例如,您可能有一个如下所示的方法:

public void doSomething(SomeObject obj) {
   // Do something to obj, assumes obj is not null
   obj.myMethod();
}

如果是这种情况,你并没有创建对象obj,而是假设在调用doSomething()方法之前已经创建了这个对象。注意,可以像这样调用该方法:

doSomething(null);

如果情况如此,obj将是null,而语句obj.myMethod()将抛出NullPointerException异常。

如果该方法的目的是执行传入对象的操作(类似上述方法的做法),那么抛出NullPointerException异常是适当的,因为这是程序员的错误,程序员需要这些信息进行调试。

除了由于方法逻辑而引发的NullPointerException异常外,还可以检查方法参数是否为null值,并通过在方法开头添加以下内容来显式抛出NPE:

// Throws an NPE with a custom error message if obj is null
Objects.requireNonNull(obj, "obj must not be null");

请注意,在错误信息中清楚地说明不能为 null 的对象是哪个对象会更有帮助。验证这一点的好处在于:1)您可以返回自己更明确的错误消息;2)对于方法的其余部分,您知道除非重新分配 obj,否则它不为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
    }
}

最后,如何使用堆栈跟踪确定异常和原因

有哪些方法/工具可用于确定原因,以便停止异常使程序过早终止?

Sonar与FindBugs可以检测NPE。 Sonar能够动态捕获JVM引起的空指针异常吗?

现在Java 14添加了一种新的语言特性来显示NullPointerException的根本原因。这个语言特性自2006年以来就已经是SAP商业JVM的一部分。

在Java 14中,以下是一个NullPointerException异常消息示例:

在线程“main”中,java.lang.NullPointerException: 无法调用“java.util.List.size()”,因为“list”为空

导致NullPointerException发生的情况列表

下面是直接*由Java语言规范提到的可能会导致NullPointerException发生的所有情况:

  • 访问(获取或设置)null引用的实例字段。(静态字段不算!)
  • 调用null引用的实例方法。(静态方法不算!)
  • throw null;
  • 访问null数组的元素。
  • 在null上同步- synchronized(someNullReference){...}
  • 任何整数/浮点运算符都可能抛出NullPointerException,如果它的操作数之一是装箱的null引用
  • 如果装箱值为null,则解箱转换会抛出NullPointerException。
  • 在空引用上调用super会抛出NullPointerException。 如果您感到困惑,这是指限定超类构造函数调用:
class Outer {
    class Inner {}
}
class ChildOfInner extends Outer.Inner {
    ChildOfInner(Outer o) { 
        o.super(); // if o is null, NPE gets thrown
    }
}
  • 使用for (element : iterable)循环来遍历一个空的集合/数组会导致空指针异常。

  • foo为null时,switch (foo) { ... }(无论是表达式还是语句)会抛出空指针异常。

  • foo为null时,foo.new SomeInnerClass() 会抛出空指针异常。

  • 形如name1::name2primaryExpression::name的方法引用在name1primaryExpression为null时会抛出空指针异常。JLS中有一个注释,表示someInstance.someStaticMethod()不会抛出NPE,因为someStaticMethod是静态的,但是someInstance::someStaticMethod仍然会抛出NPE!


615
为了避免这种类型的异常,最好在没有自己创建对象时始终检查是否为 null。如果调用者传递了 null,但是 null 不是该方法的有效参数,则将异常抛回给调用者是正确的,因为这是调用者的责任。在方法中默默地忽略无效输入并什么也不做是极其不良的建议,因为它隐藏了问题。 - Boann
121
我会为这篇文章添加一段说明,解释即使赋值给基本数据类型也可能导致自动装箱引起NPE的情况:如果b是一个Integer,那么int a=b可能会抛出NPE。在某些情况下,这会让调试变得困难和混乱。 - Simon Fischer
68
在Web浏览器中,是否有可能捕获Web应用程序抛出的NPE(NullPointerException)异常?比如说,这种异常是否会显示在Web浏览器的查看页面源代码中? - Sid
87
在调用对象的方法或尝试访问其可能具有的变量之前,请检查该对象是否等于null。有时,构造代码可以帮助避免空指针异常。例如,在使用常量字符串检查输入字符串时,应始终从常量字符串开始检查,如下所示:if ("SomeString".equals(inputString)) {} // 即使inputString为null也不会抛出异常。因此,有很多事情可以做来尝试确保安全。 - Rose
92
为了避免在您的代码中出现“NullPointerException”问题,另一种方法是使用“@Nullable”和“@NotNull”注释。以下答案提供了更多信息。尽管此答案特别针对IntelliJ IDE,但从评论中可以看出它也适用于其他工具。(顺便说一下,我没有权限直接编辑此答案,也许作者可以添加?) - Arjan Mels
显示剩余19条评论

963
NullPointerException是一种异常,当您尝试使用指向内存中无位置(null)的引用作为引用对象时,将会出现。在空引用上调用方法或尝试访问空引用的字段将触发NullPointerException。这些是最常见的情况,但其他方式列在NullPointerException javadoc页面上。我能提供的可能是用来说明NullPointerException的最简单的示例代码:
public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}
main 函数的第一行中,我明确地将 Object 的引用 obj 设置为 null。 这意味着我有一个引用,但它没有指向任何对象。 在此之后,我尝试将该引用视为指向对象,并在其上调用方法。这会导致 NullPointerException,因为引用指向的位置没有可执行的代码。
(这是一个技术细节,但我认为值得提一下:指向 null 的引用与指向无效内存位置的 C 指针不同。空指针实际上没有指向任何位置,这与指向无效位置略有不同。)

56
我理解你所写的内容,但这是因为我编程已有一段时间,并且知道什么是“指针”和“引用”(以及“null”是什么)。当我试图直接深入解释这些概念时,我的学生会眼花缭乱地看着我,因为他们没有足够的背景知识。 - mmr
28
在实践中更常见的触发空指针异常的方法是,在使用成员变量之前忘记将其显式地初始化为除 null 以外的其他值。类似于这样:链接。对于局部变量,编译器会捕获此错误,但在这种情况下它不会。也许将此内容添加到您的答案中会很有用? - Ilmari Karonen
9
@EJP,我认为你的观点是有道理的,所以我已经更新了答案,使其更加清晰,并避免使用“指向null”的说法。 - Steve Powell
8
@StevePowell,我很久以前就表示过我不希望我的答案改变,请尊重原作者的意图。 - Bill the Lizard
5
抱歉,我正在根据这个stackoverflow问题顶部的要求“改进答案”。(这个问题的答案是一个协作的过程:如果你看到可以改进的地方,请编辑答案以改进它!)我不同意你的版本更好,我认为@EJB有一些合理的观点;但是你完全可以保留你的答案,尽管它很令人困惑。 - Steve Powell
显示剩余6条评论

747

什么是NullPointerException?

开始了解最好的方法是查阅JavaDocs文档,其中已经有详细说明:

当应用程序试图在需要对象的情况下使用null时抛出此异常。这些情况包括:

  • 调用空对象的实例方法。
  • 访问或修改空对象的字段。
  • 将null长度视为数组。
  • 访问或修改空对象的槽,就像它是一个数组一样。
  • 将null作为可抛掷值抛出。

应用程序应该抛出此类的实例以指示null对象的其他非法使用。

如果你尝试将null引用与synchronized一起使用,也会导致抛出此异常,根据JLS规范也是如此。

SynchronizedStatement:
    synchronized ( Expression ) Block
  • Otherwise, if the value of the Expression is null, a NullPointerException is thrown.

如何修复它?

你遇到了一个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方法中)抛出的。查看该行并检查哪些值为null,可以通过添加日志语句或使用调试器来实现。我们发现s为null,调用其上的length方法会引发异常。当从该方法中删除s.length()时,可以看到程序停止抛出异常。 跟踪这些值来自哪里 接下来检查这个值来自哪里。通过跟踪方法的调用者,我们可以看到s是通过在print()方法中传入printString(name)来传递的,而this.name为null。 跟踪这些值应该在哪里设置 那么this.name在哪里设置?在setName(String)方法中进行设置。经过更多的调试,我们发现根本没有调用这个方法。如果调用了该方法,请确保检查调用这些方法的顺序,并且在调用打印方法之前没有调用设置方法。
这已经足够给我们一个解决方案:在调用printer.print()之前添加对printer.setName()的调用。

其他修复

变量可以具有默认值(并且setName可以防止将其设置为null):
private String name = "";

printprintString方法都可以检查是否为null,例如:

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

或者您可以设计类,使得name 始终具有非空值:

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();
    }
}

另请参阅:

我仍然找不到问题所在

如果您已经尝试过调试但是仍然没有解决方案,您可以发布一个问题来获得更多帮助,但是请确保在问题中提供您已经尝试的内容。至少需要在问题中包含堆栈跟踪信息并且标记代码中的重要行号。此外,请尝试先简化代码(参见SSCCE)。


20
调试器可以让你逐行查看程序的执行过程,了解调用哪些方法以及变量如何变化。集成开发环境(IDE)应该有一些工具来实现这一点。例如,可以参考http://www.vogella.com/tutorials/EclipseDebugging/article.html。 - fgb
20
在堆栈跟踪中看到有空指针异常时,您可以在相关方法上设置断点,并检查变量的值是否符合预期。如果您知道一个变量在不应该为 null 的情况下确实为 null,则可以在更改该变量值的任何代码周围设置断点。还有一种条件断点可用,它会告诉您变量何时发生更改。 - fgb
7
我建议使用静态分析工具,比如FINDBUGS https://en.m.wikipedia.org/wiki/FindBugs - Massimo

550

问题:什么会引起NullPointerException(NPE)?

正如您所知,Java类型分为原始类型booleanint等)和引用类型。Java中的引用类型允许您使用特殊值null,这是Java表示“没有对象”的方式。

每当您的程序试图将null用作真实引用时,运行时就会抛出NullPointerException。例如,如果您编写以下代码:

public class Test {
    public static void main(String[] args) {
        String foo = null;
        int length = foo.length();   // HERE
    }
}

标记为“HERE”的语句将尝试在null引用上运行length()方法,这将抛出NullPointerException异常。

有许多方法可以使用null值,这将导致NullPointerException异常。实际上,您唯一可以执行的null操作而不会导致NPE的是:

  • 将其分配给引用变量或从引用变量读取它,
  • 将其分配给数组元素或从数组元素读取它(前提是数组引用本身非空!),
  • 将其作为参数传递或作为结果返回, 或者
  • 使用 == != 操作符或instanceof测试它。

问题:如何阅读NPE堆栈跟踪?

假设我编译并运行上面的程序:

$ javac Test.java 
$ java Test
Exception in thread "main" java.lang.NullPointerException
    at Test.main(Test.java:4)
$

第一条观察结果:编译成功!程序中的问题不是编译错误,而是运行时错误。(有些IDE可能会警告你的程序总会抛出异常...但是标准的javac编译器不会。)

第二个观察结果:当我运行程序时,它输出了两行“胡言乱语”。错了!!那不是胡言乱语,而是一个堆栈跟踪......如果您仔细阅读,它提供了关键信息,这将帮助您跟踪代码中的错误。

所以让我们看看它说了什么:

Exception in thread "main" java.lang.NullPointerException

堆栈跟踪的第一行告诉您许多信息:

  • 它告诉您异常抛出所在的Java线程的名称。对于只有一个线程(如此示例)的简单程序,它将是“main”。接下来我们继续...
  • 它告诉您抛出的完整异常名称;即java.lang.NullPointerException
  • 如果该异常有关联的错误消息,那么在异常名称之后将输出该消息。NullPointerException在这方面是不寻常的,因为它很少有错误消息。

第二行是诊断NPE最重要的一行。

at Test.main(Test.java:4)

这告诉我们一些事情:

  • "at Test.main" 表示我们在 Test 类的 main 方法中。
  • "Test.java:4" 给出了类的源文件名,同时告诉我们该语句位于文件的第 4 行。

如果你数一下文件中的行数,第 4 行是我用“HERE”标签标记的那一行。

请注意,在更复杂的例子中,NPE堆栈跟踪中会有很多行。但你可以确定第二行(第一个“at”行)将告诉你 NPE 抛出的位置1

简而言之,堆栈跟踪将明确告诉我们程序哪个语句抛出了 NPE。

另请参见:什么是堆栈跟踪,如何使用它来调试应用程序错误?

1 - 不完全正确。有一种叫做嵌套异常的东西……

问题:如何追踪代码中 NPE 异常的原因?

这是困难的部分。简短的答案是,通过对堆栈跟踪、源代码和相关 API 文档提供的证据进行逻辑推理。

让我们首先用简单的例子来说明。我们从堆栈跟踪告诉我们 NPE 发生位置开始:

int length = foo.length(); // HERE

如何会发生NPE呢?只有一种情况:当foo的值为null时,我们尝试在null上运行length()方法,结果......出现错误!

但是(也许你会问),如果NPE是在length()方法调用内部抛出的呢?

好吧,如果发生了这种情况,堆栈跟踪将会不同。第一个“at”行将表示异常在java.lang.String类的某一行中抛出,并且Test.java的第4行将成为第二个“at”行。

那么这个null来自哪里呢?在这种情况下,很明显,我们需要做什么来解决它。(给foo赋一个非空值。)

好的,现在让我们尝试一个稍微棘手一点的例子。这需要一些逻辑推断。

public class Test {

    private static String[] foo = new String[2];

    private static int test(String[] bar, int pos) {
        return bar[pos].length();
    }

    public static void main(String[] args) {
        int length = test(foo, 1);
    }
}

$ javac Test.java 
$ java Test
Exception in thread "main" java.lang.NullPointerException
    at Test.test(Test.java:6)
    at Test.main(Test.java:10)
$ 

现在我们有两个“at”行。第一个是针对这一行的:

return args[pos].length();

第二个是针对这行代码:

int length = test(foo, 1);
    

看看第一行,它怎么会抛出NPE(NullPointerException)?有两种情况:

  • 如果bar的值为null,那么bar[pos]将抛出NPE。
  • 如果bar[pos]的值是null,那么在它上调用length()将抛出NPE。

接下来,我们需要找出哪种情况可以解释实际发生了什么。我们将从探究第一种情况开始:

bar从何而来?它是test方法调用的参数,如果我们查看如何调用test,我们可以看到它来自foo静态变量。此外,我们可以清楚地看到我们将foo初始化为非空值。这就足以暂时排除这种情况。(理论上,其他东西可能会将foo更改为null...但这里没有发生。)

那么我们的第二种情况呢?嗯,我们可以看到pos1,这意味着foo[1]必须是null。这是可能的吗?

是可以的!这就是问题所在。当我们像这样初始化时:

private static String[] foo = new String[2];

我们分配了一个包含两个元素的String[],这些元素被初始化为null。此后,我们没有改变foo的内容...所以foo[1]仍将是null

那在Android上呢?

在Android上,追踪NPE的直接原因会简单一些。异常消息通常会告诉您使用空引用的(编译时)类型以及抛出NPE时尝试调用的方法。这简化了确定直接原因的过程。

但是在另一方面,Android有一些特定于平台的常见NPE原因。一个非常普遍的情况是getViewById意外返回了null。我的建议是搜索关于意外null返回值原因的问题和答案。


453

好比你在尝试访问一个为null的对象。考虑下面的示例:

TypeA objA;

此时您只是声明了这个对象,但尚未初始化或实例化。当您尝试访问其中的任何属性或方法时,它将抛出NullPointerException,这是有道理的。

同时参考下面这个示例:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown

4
如果我们执行 System.out.println(a.length());,会抛出 NullPointerException 异常,为了避免这种情况,我们可以使用 try catch 块进行异常处理。谢谢 - Vijaya Varma Lanke

380

当应用程序试图在需要对象的情况下使用null时,将抛出空指针异常。这些情况包括:

  1. 调用null对象的实例方法。
  2. 访问或修改null对象的字段。
  3. 将null的长度视为数组。
  4. 访问或修改null的插槽,就好像它是一个数组。
  5. 将null作为Throwable值抛出。

应用程序应该抛出这个类的实例来指示对null对象的其他非法使用。

参考:http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html


15
访问未初始化对象的属性。 - Emiliano
8
访问已初始化的属性本身不会导致 NPE。而是在使用未初始化的属性值时才会导致 NPE。请注意,此处的重点在于“使用”,即对该值进行操作。 - Stephen C
4
如果您需要更多的案例:1)将“null”用作“synchronized”块的目标,2)将“null”用作“switch”的目标,并取消装箱“null”。 - Stephen C

358
一个null指针是指向无处的指针。当你引用一个指针p时,你会说“给我存储在‘p'中的位置上的数据”。当p是一个null指针时,“p”所存储的位置是“无处”,你相当于在说“给我在‘无处’位置上的数据”。显然,它做不到这点,因此会抛出一个null指针异常
总的来说,这通常是因为某些东西没有正确地初始化。

8
“空指针是指向无所指的指针” 我不同意。空指针并不是指向“无处”的,而是指向“空值”的。 - TheRealChx101

347
很多解释已经存在,以解释它是如何发生和如何修复的,但你也应该遵循最佳实践,以避免在任何情况下出现NullPointerException
另请参见: 一个很好的最佳实践列表 我想补充一点,非常重要的是,要充分利用final修饰符。 在Java中尽可能使用“final”修饰符 摘要:
  1. 使用 final 修饰符来确保良好的初始化。
  2. 避免在方法中返回 null,例如在适用时返回空集合。
  3. 使用注释 @NotNull@Nullable
  4. 快速失败并使用断言来避免将不应为 null 的对象通过整个应用程序传播。
  5. 首先使用已知对象的 equals 方法: if("knownObject".equals(unknownObject)
  6. 优先使用 valueOf() 而不是 toString()
  7. 使用 null 安全的 StringUtils 方法 StringUtils.isEmpty(null)
  8. 在方法中使用 Java 8 的 Optional 作为返回值,Optional 类提供了一种表示可选值而不是 null 引用的解决方案。

7
在j2ee项目中,空指针异常非常普遍。某些情况下,引用变量会得到null值。因此,您应该正确检查变量的初始化。在条件语句中,您应该始终检查标志或引用是否包含null,例如:如果(flag!= 0) { 使用标志的代码 } - Amaresh Pattanayak
18
值得一提的是,一些集成开发环境(例如 Eclipse)基于可定制的注解(如上述的 @Nullable)提供自动空值分析,并警告可能存在的错误。还可以根据现有代码结构推断和生成这样的注解(例如 IntelliJ 可以做到这一点)。 - Jan Chimiak
7
在使用可为空对象之前,首先应该检查它是否为空,使用 if (obj==null) 进行判断。如果它是空的,则需要编写代码来处理它。请注意不改变原意。 - Lakmal Vithanage
7
在可能的情况下,最好避免在方法中返回空对象,并在不允许使用空输入参数的情况下使用注释来减少代码中的´if (obj==null)´数量,从而通过约定提高代码的可读性。 - L. G.
7
在您接受这些“最佳实践”为真理之前,请阅读此链接:http://www.satisfice.com/blog/archives/27 - Stephen C
显示剩余6条评论

340

空指针异常表示您在未初始化对象的情况下使用它。

例如,以下是一个学生类,将在我们的代码中使用它。

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

以下代码会导致空指针异常。

public class School {

    Student student;

    public School() {
        try {
            student.getId();
        }
        catch(Exception e) {
            System.out.println("Null pointer exception");
        }
    }
}
因为您正在使用student,但您忘记像下面正确的代码一样初始化它:
public class School {

    Student student;

    public School() {
        try {
            student = new Student();
            student.setId(12);
            student.getId();
        }
        catch(Exception e) {
            System.out.println("Null pointer exception");
        }
    }
}

12
虽然这是一个很好的例子,但我可以问一下它对问题的补充是什么,而其他所有答案都已经涵盖了吗? - Mysticial
18
在这里使用“未初始化”的词语是不合适的。你展示的例子实际上是“已初始化”的,且是用null进行了初始化。对于未初始化的变量,编译器会提出警告。 - Adrian Shum

339
在Java中,除了基本类型,所有的东西都是以类的形式存在。
如果你想使用任何对象,那么有两个阶段:
声明
初始化
例如:
声明:`Object object;`
初始化:`object = new Object();`
数组概念也是一样的:
声明:`Item item[] = new Item[5];`
初始化:`item[0] = new Item();`
如果没有给出初始化部分,则会出现`NullPointerException`。

6
调用实例的方法时经常会出现 NullPointerException。例如,如果您声明一个引用但没有将其指向任何实例,则在调用其方法时会发生 NullPointerException。 例如: YourClass ref = null; // 或 ref = anotherRef; // 但 anotherRef 尚未指向任何实例 ref.someMethod(); // 这将抛出 NullPointerException。通常可以通过以下方式解决: 在调用该方法之前,确定引用是否为 null。 例如: if (yourRef != null) { yourRef.someMethod(); } - sunhang
5
或者使用异常捕获: 例如: 尝试 { yourRef.someMethod(); } 捕获 (NullPointerException e) { // TODO } - sunhang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接