可能重复:
How come invoking a (static) method on a null reference doesn’t throw NullPointerException?
Static fields on a null reference in Java
我尝试了this old video的代码:
class Impossible {
public static void main(String[] args) {
Thread t = null;
System.out.println(t.currentThread().getName());
}
}
输出:main
嗯,那到底是什么?! java.lang.Thread
违反任何NullPointerException
规则吗?
但是我最感兴趣的是:如何让该变量表现为抛出NullPointerException?
答案 0 :(得分:10)
java.lang.Thread是否违反任何NullPointerException规则?
否,抛出NPE
的原因与class
无关。它与该类的instance
相关,在该类上进行调用。此外,它取决于您访问的方法或字段的类型。
这里发生的是,currentThread()
是Thread类的静态方法。这是一个类,而不是一个实例。因此,即使您在Thread类的引用上调用它,它实际上也是在类名上调用的。
所以,
Thread t = null
t.currentThread();
实际上被调用为: -
Thread.currentThread();
因此,当通过对象引用表达式访问静态成员时,只有声明的引用类型才对。这意味着:
引用实际指向null无关紧要,因为没有 实例是必需的。
如果引用不为null,则类型无关紧要 引用所指向的对象,没有动态分派。
如何使该变量表现为抛出NullPointerException?
好吧,当前的print语句永远不会抛出NPE
。第一部分已经在上面解释过。现在,让我们继续前进。
Thread.currentThread();
上述调用永远不会返回null
。它总是返回当前的线程实例。在Java中,您总是在一个或另一个线程内。即使在public static void main
方法内,您也在执行Main Thread
。因此,currentThread
不能是null
。
因此,进一步调用: -
Thread.currentThread().getName();
将正常工作,并返回当前线程的名称。
答案 1 :(得分:3)
currentThread()
是类static
的{{1}}方法。这意味着它不与类的任何特定实例相关联,而是与类本身相关联。
考虑到这一点,Thread
只是说t.currentThread()
的另一种方式。 Thread.currentThread()
的值根本没有使用,因此t
是否为t
并不重要。
答案 2 :(得分:0)
You can't throw a NullPointerException by calling a static method。所以你需要调用一个实例方法 - 任何实例方法都可以,例如:
t.checkAccess();
t.getId();
t.getName();
等
答案 3 :(得分:0)
如果你在开发环境(Eclipse / Netbeans)中看到代码,你会在第一时间看到currentThread()
写成草书,这清楚地表明它是一个静态方法(类方法)。 BR />
此外,如果启用了checkstyle,它将警告您不要在对象的实例上调用静态方法。
问题有点像犯规,因为此处的代码格式无法显示格式不同的静态方法。
最后回答这个问题:类Thread永远不会为null,类的实例可以为null。