Static變量的總結
1.不可從一個static方法內部發出對非static方法的調用,盡管反過來說是可以的。如果要在static方法中訪問所在類的成員變量或方法,就必須首先創建相應的實例變量。
2.static變量可以通過類名直接訪問,
3.static方法不能被覆蓋,但是在子類中可以聲明與父類驚天方法相同的方法,從而將父類的靜態方法隱藏,另外自樂不能把父類的非靜態方法重寫為靜態的:并且static方法也不能夠重載(因為他們是前期綁定的,所以不能重載;不能重載的方的還有final、private)
而普通方法能被覆蓋,覆蓋的結果是產生多態;
例子:
package test;
class Test {
public static void main(String[] args) {
A a = new B();
a.f();
a.m();
}
}
class A {
public static void f() {
System.out.println("hello,A");
}
public void m() {
System.out.println("hello,A");
}
}
class B extends A {
public static void f() {
System.out.println("hello,B");
}
public void m() {
System.out.println("hello,B");
}
}
結果是:
hello,A
hello,B
1.根據Java Language Specification (Version 3) 8.4.8 的描述,子類在繼承父類時,對于方法而言,存在兩種關系:
A. override 即覆蓋,這是對實例方法(instance method)而言的;子類與父類中形構相同的方法(原文中是 subsignature,它的范圍比“形構相同”要大,請參考原文)會override 父類中的那個方法。
B. hide 即隱藏,這是對類方法(class method)即static 方法而言的。如果子類中定義了靜態方法,則它會隱藏父類中形構相同的(原文中是 subsignature,它的范圍比“形構相同要”大,請參考原文)所有方法,但如果隱藏了父類中的實例方法,則會編譯報錯。
2.根據上面的規范:
“override 覆蓋”的前提是實例方法,只有實例方法在繼承時才會出現override情況。
如果是static方法,在繼承時出現的現象根本就不能用“override”這個詞描述,如果static方法在父類和子類中形構一致,則被成為 hide(隱藏)。
3.因為static方法是類方法,實現時是靜態綁定的(引用“JAVA 核心技術 卷1 第六版”中149頁內容“private、static、final”修飾的方法是靜態綁定的。其他的方法在運行時動態綁定。“interhanchi”所說的“static和final方法外都是后期綁定”并不精確),只與類相關,不會有多態性。 從編程的角度看,效果好像是“static方法不能被覆蓋”;
4.從術語上看,“static方法能否被覆蓋”這種說法本身就是錯誤的,因為“覆蓋”定義的前提和基礎是實例方法。
5.結論: 子類中的static方法會隱藏父類中形構相同的static方法。
final變量的總結:
Final不想做改變的理由是:設計和效率
在java中除了static方法、final方法、(private方法屬于final方法)之外,其他所有的方法都是后期綁定
Final可以修飾基本類型,也可以修飾引用類型,但是當final修飾引用類型的時候,不能夠改變引用指向另一個對象, 但這個對象本身的狀態是可以改變的...
final String string=“final”;
是開辟了2個內存空間,在棧中的string引用在堆中的final,其中string是始終指向堆中的final這個地址的引用,不能改變。但是堆中的final卻可以改變。
可以通過下面的例子來說明static final的作用:
public class Test0
{
private static final String string;
public Test0(String str)
{
string=str;
System.out.println(string);
}
public static void main(String[] args)
{
Test0 t=new Test0("hello world");
Test0 tt=new Test0("world hello");
}
}
解釋說明:
1.首先正確的認識一下final, 一個final修飾的叫"終態", 而這種終態很特殊, 它指的是:"當這個變量被賦值之后成為終態". 那么,當一個被賦值之后的final修飾變量, 將不可再被賦新值. (先理解)
2.而static表示靜態變量, 說穿了,你需要知道JAVA如何為一個類創建內存空間--我們知道類有空間,類產生的實例(對象)有空間,方法有空間,變量有空間, 當static修飾時, 這個變量會在類分配內存時就被分配內存了, 所以你知道,你可以不用產生對象就使用靜態變量.
3.好了,有了以上兩點,我們來看看, 你可以根據我的敘述試試. 首先,你只使用final修飾你的string, 你會發現不會報錯, 因為這是一個"還沒有被賦值的非靜態的終態變量(在類分配內存時不會分配內存).好,接下來你改一下,寫:private final String string = "sss"; 你會發現報錯了,原因自己想.
接下來, 看你發出來的代碼, 又被static修飾,又被final修飾,首先它是一個靜態變量, 那么在類分配時就會分配內存, 實際上這個String就被初始化了,既然初始化了, 那么也就有值了, 而一個終態被賦值變量將不能再被賦值, 那么自然就報錯了