public class Main
{
public static void main(String []ar)
{
A m = new A();
System.out.println(m.getNull().getValue());
}
}
class A
{
A getNull()
{
return null;
}
static int getValue()
{
return 1;
}
}
我在SCJP书中遇到过这个问题。代码打印出1
而不是预期的NPE。有人可以解释相同的原因吗?
答案 0 :(得分:22)
基本上你正在调用静态方法,好像它是一个实例方法。这只是解决了静态方法调用,所以就像你写的那样:
A m = new A();
m.getNull();
System.out.println(A.getValue());
IMO事实上你的代码是合法的,这是Java中的一个设计缺陷。它允许您编写非常具有误导性的代码,我总是使用Thread.sleep
作为示例:
Thread thread = new Thread(someRunnable);
thread.start();
thread.sleep(1000);
哪个线程会发送到睡眠状态?目前的“当然”......
答案 1 :(得分:18)
根据Java Language Specification:
的行为可以使用null引用来访问类(静态)变量,而不会导致异常。
答案 2 :(得分:6)
静态方法调用在编译时解析。编译器看到getNull()
的返回值类型为A
,它具有静态getValue()
方法(并且没有相同名称的实例方法),因此在字节码中,实际返回值忽略getNull()
,并调用A.getValue()
。
答案 3 :(得分:1)
getNull函数返回一个A对象。 getValue被声明为static,只需要class_name来运行,就像在A.getValue()中一样。因为getNull返回(实际上)一个A对象......你将得到1
答案 4 :(得分:1)
<强>的System.out.println(m.getNull()的getValue()); 强> 这行代码与 System.out.println(A.getValue());
因为 getValue()方法是静态的,并且所有静态调用都是在java 的编译时启动的。所以一旦你在非静态中使用 getValue()就不会产生任何错误,这会产生错误,因为它会在运行时被调用