我正在寻找一些问题,并引导我解决这个问题。在对象实例上调用静态方法时,它是动态还是静态解析,例如:
class A
{
public static foo() {}
}
class B extends A
{
public static foo() {}
}
[...]
public static void main(String[] args)
{
A a = new B();
a.foo(); // does this all A foo or B foo?
}
为什么我问这是因为它可以解释为什么静态方法不能抽象。因为如果A是一个接口,如果foo是抽象的和静态的,这将不起作用。
这在内部如何运作?基本上如果知道foo是静态的,如果它不做任何动态的话怎么样?是不是还要检查班级?如果它知道a真的是B为什么不在B上调用foo?
答案 0 :(得分:6)
它根据a
的编译时类型静态解析它。该值被忽略,甚至可以为null:
A a = null;
a.foo(); // Still calls A.foo
IIRC,有一次 执行了无效检查,但现在没有。
我会强烈敦促你不要这样做,至少有些IDE(包括Eclipse)会警告你这件事。代码看起来不像它,有时它可能非常误导:
Thread t = new Thread(new Runnable() { /* ... */ });
t.start();
t.sleep(1000);
看起来就像它使新创建的线程休眠 - 但实际上它是当前线程将睡眠。 EEK!
IMO,这实际上是Java设计中的一个错误。