一般情況下,需要用到某個類的時候,都必須先實例化這個類,才能對其進行調用。在編程過程中發現,有些類不用實例化就可以直接拿來使用,使用它的字段、方法等等。
這時候,靠的就是static作用。static英文意思為“靜止的,靜態的”,在OOP中可以作為修飾符,類、字段、屬性、方法等被static修飾後,變為靜態類、靜態字段、靜態屬性、靜態方法……
static修飾的類成為靜態類,靜態類中只能包含靜態成員(被static修飾的字段、屬性、方法),不能被實例化,不能被繼承;非靜態中可以包含靜態成員。
1、被調用時必須先實例化的情況:
被調用成員為非靜態成員(此時它所屬的類肯定為非靜態類)。如下小例子:
public class ClassA //ClassA類(非靜態類) { public ClassA() { } //構造函數 public void Fun() { }//ClassA類中的方法(非靜態方法) } public class ClassB //需要調用ClassA類中方法的ClassB類 { public ClassB() { } //構造函數 public void Fun() { ClassA a = new ClassA();//調用ClassA類中的方法需要先實例化 a.Fun(); } }
說明:ClassA類為非靜態類,其中的方法Fun()也為非靜態方法,所以在ClassB中調用時需要先實例化ClassA類。
2、被調用時不需要實例化的情況:
被調用成員為靜態成員(此時它所屬的類為靜態類或非靜態類)。如下小例子:
(1)被調用類為非靜態類:
public class ClassA //ClassA類(非靜態類) { public ClassA() { } //構造函數 public static void Fun() { }//ClassA類中的方法(靜態方法) } public class ClassB //需要調用ClassA類中方法的ClassB類 { public ClassB() { } //構造函數 public void Fun() { ClassA.Fun(); //調用ClassA類中的方法直接調用:類名.成員 } }
說明:ClassA類為非靜態類,但其中的方法Fun()為非靜態方法,所以在ClassB中調用時不實例化ClassA類(而且不能實例化),直接調用其成員,語法為“類名.成員”。
(2)被調用類為靜態類:
public static class ClassA //ClassA類(靜態類) { //當然靜態類中不能存在構造函數 public static void Fun() { }//ClassA類中的方法(靜態方法) } public class ClassB //需要調用ClassA類中方法的ClassB類 { public ClassB() { } //構造函數 public void Fun() { ClassA.Fun(); //調用ClassA類中的方法直接調用:類名.成員 } }
說明:ClassA類為靜態類,其中的方法也Fun()為非靜態方法,所以在ClassB中調用時不實例化ClassA類(而且不能實例化),直接調用其成員,語法為“類名.成員”。
(1) 用來修飾類或類的成員,這時不需要創建實例就能訪問(而且不能實例化),在被調用的時候自動實例化,且在內存中產生一個實例。當含有靜態成員的非靜態類實例化出對象後,這些對象公用這些靜態成員,通過類名或對象名都能訪問它們。
在網上看到兩個有趣的小例子:
人是一個非靜態類。人有腦子,這是一個用static修飾的屬性。
這個屬性是針對所有的人,是人的共同特征。而不是某個特點對象所特有的(比如張三有腦子,李四沒腦子),因為只要是個人,他都有腦子(雖然卡洛斯·羅德裡格茲只有半個腦子,還有些人比較腦殘→_→,那也算是有腦子),既然是人類共有的,那麼他就不能被實例化。
另外一個能被實例化的例子,還是人這個類,人的身高,就是一個非static的屬性。因為每個人的身高是不同的。比如我身材魁梧,高達1.55米,這個1.55米是描述我的身高,是跟我這個特定的對象有聯系的。姚明才2.26米,這是姚明這個對象的數據。不管是1.55還是2.26,這都和特定的對象有聯系,而不是人類所共有的特征。所以非static的可以被實例化,而static不能被實例化。
(2) 修飾方法內部的靜態變量:
我們的代碼都是從硬盤加載到內存中才能運行的,在內存中主要分為三個區域,來存放我們的代碼,分別是堆、棧和靜態存儲區。堆中存放的是代碼中的引用類型變量,如類的實例、數組等;棧中存放的是代碼中的值類型,如整型、浮點型、布爾型等;靜態存儲區中存放靜態變量和全局變量、常亮。
整個程序運行時,代碼都是共用靜態存儲區中的靜態變量的,例如定義存款余額為靜態變量,同一個銀行卡號,無論你是在銀行取錢、在ATM機取錢,還是網銀消費,用的都是這個靜態的余額。
所以,方法內部的靜態變量,執行完靜態變量值不消失,再次執行此對象的方法時,值仍存在,它不是在堆和棧中分配的,是在靜態區非配的, 這是與局部變量最大的區別。
作者:csdn博客 胡玉洋