動態綁定是指編譯器在編譯階段不知道要調用哪一個方法,直到運行時才能肯定。讓咱們用個例子來解釋。譬如咱們有一個叫做’SuperClass’的父類,還有一個繼承它的子類’SubClass’。如今SuperClass引用也能夠賦給SubClass類型的對象。若是SuperClass中有個someMethod()的方法,而子類也重寫了這個方法,那麼當調用SuperClass引用的這個方法的時候,編譯器不知道該調用父類仍是子類的方法,由於編譯器不知道對象究竟是什麼類型,只有到運行時才知道這個引用指向什麼對象。 git
1
2
3
4
5
6
7
8
|
...
SuperClass superClass1 =newSuperClass();
SuperClass superClass2 =newSubClass();
...
superClass1.someMethod();// SuperClass version is called
superClass2.someMethod();// SubClass version is called
....
|
咱們能夠看到雖然對象引用superClass1和superClass2都是SuperClass類型的,可是在運行時它們分別指向SuperClass和SubClass類型的對象。 github
因此在編譯階段,編譯器不清楚調用引用的someMethod()究竟是調用子類仍是父類的該方法。 spa
因此方法的動態綁定是基於實際的對象類型,而不是它們聲明的對象引用類型。 htm
若是編譯器能夠在編譯階段就完成綁定,就叫做靜態綁定或前期綁定。基本上實例方法都在運行時綁定,全部的靜態方法都在編譯時綁定,因此靜態方法是靜態綁定的。由於靜態方法是屬於類的方法,能夠經過類名來訪問(咱們也應該使用類名來訪問靜態方法,而不是使用對象引用來訪問),因此要訪問它們就必須在編譯階段就使用編譯類型信息來進行綁定。這也就解釋了爲何靜態方法實際上不能被重寫。 對象
更多閱讀:能夠重寫靜態方法嗎? 繼承
相似的,訪問成員變量也是靜態綁定的,由於Java不支持(其實是不鼓勵)成員變量的多態行爲。下面看個例子: ci
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
classSuperClass{
...
publicString someVariable ="Some Variable in SuperClass";
...
}
classSubClassextendsSuperClass{
...
publicString someVariable ="Some Variable in SubClass";
...
}
...
...
SuperClass superClass1 =newSuperClass();
SuperClass superClass2 =newSubClass();
System.out.println(superClass1.someVariable);
System.out.println(superClass2.someVariable);
...
|
輸出: get
1
2
|
Some Variable in SuperClass
Some Variable in SuperClass
|
咱們能夠發現成員變量由對象引用聲明的類型決定,是由編譯器在編譯階段就知道的信息,因此是靜態綁定。另一個靜態綁定的例子是私有的方法,由於它們不會被繼承,編譯器在編譯階段就完成私有方法的綁定了。 編譯器