2014-03-02 28 views
5

我需要在Java的Dynamic多態中做一個說明。指向基類的動態多態性引用

class Foo { 
    int a=3; 
    public void display() { 
    System.out.println(" in foo "+a); 
    } 
} 

class Bar extends Foo { 
    int a=8; 
    public void display() { 
    System.out.println(" in boo "+a); 
    } 
} 

public class Tester { 
public static void main(String[]args) { 
    Foo f = new Bar(); 
    f.display(); 
    System.out.println(f.a); 
} 
} 

在這裏,當我創建具有基類引用一個子類對象時,在調用方法f.display()它給我的輸出作爲in boo 8。這是因爲動態多態性,它在運行時檢查對象類型以調用該方法。

現在在打印f.a時會打印3,因爲變量不能在java中重寫,因此稱爲隱藏。這就是爲什麼它顯示基本變量值而不是子變量值。

現在我的問題是f是指向子類對象的基類的引用。那麼f.a如何指向基本變量。 幕後發生了什麼?引用如何指向基類?

(我知道規則,但我想知道如何/爲什麼?)

回答

4

我不知道這是不是外面你學到的東西,但在這裏它是。編譯代碼時,編譯器會生成JVM執行的字節碼。

到外地Foo.af.a在線路

System.out.println(f.a); 

參考被編譯到

getfield  #6     // Field Foo.a:I 

其中getfielda bytecode instruction其中

獲得的對象的字段值objectref,其中字段爲通過場參考常量池中索引識別(index1之間< +索引2)

和常量池

Constant pool: 
    // [...] 
    #6 = Fieldref   #20.#24  // Foo.a:I 
    // [...] 

所以字節代碼被引用在Foo類的字段,申報類型的變量,而不是實例的運行時類類型。


你可以看一下生成的字節碼用下面的命令

javap -c -v YourClass 
4

這是因爲你已經在你的問題說:

變量不能在覆蓋Java

因此,編號f.a在編譯時被靜態解析,並且它將編譯器帶到Foo.a,即3

0

因爲變量不能被重寫,你給從基類的引用,爲什麼它

print f.a = 3 

如果你聲明這樣

Bar f = new Bar(); 

,現在你打印的f.a價值它給你8