2012-04-01 118 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

相關問題