在对象实例上调用静态方法和侧面注释Java

时间:2012-04-01 06:57:34

标签: 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 B foo?
}

为什么我问这是因为它可以解释为什么静态方法不能抽象。因为如果A是一个接口,如果foo是抽象的和静态的,这将不起作用。

这在内部如何运作?基本上如果知道foo是静态的,如果它不做任何动态的话怎么样?是不是还要检查班级?如果它知道a真的是B为什么不在B上调用foo?

1 个答案:

答案 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设计中的一个错误。