在对象实例上调用静态方法和Java旁注

在对象实例上调用静态方法和Java旁注,java,Java,我一直在寻找一些问题,这让我想到了这个问题。在对象实例上调用静态方法时,它是动态解析还是静态解析,例如: 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

我一直在寻找一些问题,这让我想到了这个问题。在对象实例上调用静态方法时,它是动态解析还是静态解析,例如:

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?
}
我之所以问这个问题,是因为它可以解释为什么静态方法不能是抽象的。因为如果一个接口是一个接口,那么如果foo是抽象的和静态的,这就不起作用了


这在内部是如何工作的?基本上,如果它不做任何动态的事情,它怎么知道foo一开始是静态的呢?它不是还要检查班级吗?另外,如果它知道a实际上是B,为什么不在B上调用foo呢?

它根据
a
的编译时类型静态地解析它。该值被忽略,甚至可以为空:

A a = null;
a.foo(); // Still calls A.foo
IIRC,它曾经执行过空值检查,但现在没有

我强烈敦促您不要这样做,至少一些IDE(包括Eclipse)可以警告您这一点。代码并不像看上去的那样,有时可能会产生误导:

Thread t = new Thread(new Runnable() { /* ... */ });
t.start();
t.sleep(1000);
这看起来会使新创建的线程休眠,但实际上是当前线程将休眠。哎呀


在我看来,这实际上是Java设计中的一个错误。

它基于
a
的编译时类型静态地解决了这个问题。该值被忽略,甚至可以为空:

A a = null;
a.foo(); // Still calls A.foo
IIRC,它曾经执行过空值检查,但现在没有

我强烈敦促您不要这样做,至少一些IDE(包括Eclipse)可以警告您这一点。代码并不像看上去的那样,有时可能会产生误导:

Thread t = new Thread(new Runnable() { /* ... */ });
t.start();
t.sleep(1000);
这看起来会使新创建的线程休眠,但实际上是当前线程将休眠。哎呀


在我看来,这实际上是Java设计中的一个错误。

似乎没有人能比得上你的速度:)似乎没有人能比得上你的速度:)