可能的重复:
为什么在空引用上调用(静态)方法不会抛出 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?
java.lang.Thread 是否违反了任何 NullPointerException 规则?
不,抛出NPE
的原因与class
无关。它与该类的instance
相关,在其上执行调用。此外,这取决于您正在访问的方法或字段的类型。
这里发生的事情是,currentThread()
是 Thread 类的静态方法。这是对类的侮辱,而不是实例。因此,即使您在 Thread 类的引用上调用它,它实际上是在类名上调用的。
所以
Thread t = null
t.currentThread();
实际上调用为: -
Thread.currentThread();
因此,当通过对象引用表达式访问静态成员时,只有声明的引用类型很重要。这意味着:
引用是否实际指向 null 并不重要,因为没有 实例是必需的。
如果引用不为 null,则类型无关紧要 对于引用指向的对象,没有动态调度。
如何使该变量的行为成为抛出 NullPointerException?
好吧,当前的打印语句永远不会抛出NPE
.第一部分已经在上面解释过了。现在,让我们继续前进。
Thread.currentThread();
上述调用永远不会返回null
。它始终返回当前线程实例。在 Java 中,你总是在一个或另一个线程中。即使在方法public static void main
内部,您也在执行Main Thread
。所以,currentThread
不能null
.
因此,进一步调用:-
Thread.currentThread().getName();
将正常工作,并返回当前线程的名称。
currentThread()
是类Thread
的static
方法。这意味着它不与类的任何特定实例相关联,而是与类本身相关联。
考虑到这一点,t.currentThread()
只是一种不同的Thread.currentThread()
说法。根本不使用t
的值,因此t
是否null
并不重要。
不能通过调用静态方法抛出 NullPointerException。所以你需要调用一个实例方法 - 任何实例方法都可以,例如:
t.checkAccess();
t.getId();
t.getName();
等。
如果你在开发环境(Eclipse/Netbeans)中看到这段代码,你会在第一时间看到currentThread()
是草书的,这清楚地表明它是一个静态方法(类方法)。
此外,如果您启用了 checkstyle,它将警告您不要在对象的实例上调用静态方法。
这个问题有点犯规,因为这里的 Code 格式不能显示不同格式的静态方法。
最后回答这个问题:类线程永远不会为空,类的实例可以为空。