8

可能重复:
为什么在空引用上调用(静态)方法不会抛出 NullPointerException?
Java中空引用上的静态字段

我尝试了这个旧视频中的代码:

class Impossible {
    public static void main(String[] args) {
        Thread t = null;
        System.out.println(t.currentThread().getName());
    }
}

输出:main

好吧,那到底是什么?!是否java.lang.Thread违反任何NullPointerException规则?

但我最感兴趣的是:如何使该变量表现得抛出 NullPointerException?

4

4 回答 4

10

java.lang.Thread 是否违反任何 NullPointerException 规则?

NPE,a被抛出的原因与 a无关class。它与该类的一个相关,instance在该类上完成调用。此外,这取决于您访问的方法或字段的类型。

这里发生的是,currentThread()是 Thread 类的静态方法。这是绑定到一个类,而不是一个实例。因此,即使您在 Thread 类的引用上调用它,它实际上也是在类名上调用的。

所以,

Thread t = null
t.currentThread();

实际上被调用为: -

Thread.currentThread();

因此,当通过对象引用表达式访问静态成员时,只有引用的声明类型很重要。这意味着:

  • 引用是否实际指向 null 并不重要,因为不需要实例。

  • 如果引用不为空,则无论引用指向的对象的类型是什么,都没有动态调度。


如何使该变量表现得抛出 NullPointerException?

好吧,当前的 print 语句永远不会抛出NPE. 第一部分已经在上面解释过了。现在,让我们继续前进。

Thread.currentThread();

上面的调用永远不会返回null。它总是返回当前线程实例。在 Java 中,你总是在一个或另一个线程中。即使在内部public static void main方法中,您也在执行Main Thread. 所以,currentThread不能null

因此,进一步调用: -

Thread.currentThread().getName();

可以正常工作,并返回当前线程的名称。

于 2012-11-24T09:42:10.343 回答
3

currentThread()static类的方法Thread。这意味着它不与类的任何特定实例相关联,而是与类本身相关联。

考虑到这一点,t.currentThread()简直就是另一种说法Thread.currentThread()。的值根本没有使用,所以是否是t无关紧要。tnull

于 2012-11-24T09:43:36.663 回答
0

如果您在开发环境(Eclipse / Netbeans)中看到该代码,您会在第一时间看到currentThread()草书,这清楚地表明它是一个静态方法(类方法)。

此外,如果您启用了 checkstyle,它会警告您不要在对象实例上调用静态方法。

这个问题有点犯规,因为这里的代码格式不能显示不同格式的静态方法。

最后回答这个问题:类线程永远不会为空,类的实例可以为空。

于 2012-11-24T16:33:31.173 回答
0

您不能通过调用静态方法抛出 NullPointerException。所以你需要调用一个实例方法——任何实例方法都可以,例如:

t.checkAccess();
t.getId();
t.getName();

等等

于 2012-11-24T10:02:08.217 回答