2012-04-01 87 views
1

我正在查看一些问题,并且引发了这个问题。当你调用一个对象实例的静态方法,它的动态或静态解决,例如:在对象实例和旁注上调用静态方法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是静态的,如果它没有做任何动态的动作?是不是还要检查班级?另外如果它知道一个真的是B,为什么不把它叫做B上的foo?

回答

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); 

看起来像它使新创建的线程睡眠 - 但实际上它是当前螺纹,其会睡。伊克!

IMO,这在Java设计中实际上是一个错误。

+0

似乎没有人可以匹配你的速度:) – aviad 2012-04-01 07:00:53

+0

我想这就是为什么他们不允许它,非常好的答案:-) – rubixibuc 2012-04-01 07:07:21

相关问题