1. static的做用和特色
能夠用來修飾:成員變量,成員方法,代碼塊,內部類等。具體以下所示java
修飾成員變量和成員方法app
- 被 static 修飾的成員屬於類,不屬於單個這個類的某個對象,被類中全部對象共享,能夠而且建議經過類名調用。
- 被static 聲明的成員變量屬於靜態成員變量,靜態變量存放在Java內存區域的方法區。
靜態代碼塊ide
- 靜態代碼塊定義在類中方法外,靜態代碼塊在非靜態代碼塊以前執行(靜態代碼塊—>非靜態代碼塊—>構造方法)
- 該類無論建立多少對象,靜態代碼塊只執行一次.
靜態內部類(static修飾類的話只能修飾內部類)測試
靜態內部類與非靜態內部類之間存在一個最大的區別:this
- 非靜態內部類在編譯完成以後會隱含地保存着一個引用,該引用是指向建立它的外圍內,可是靜態內部類卻沒有。沒有這個引用就意味着:1.它的建立是不須要依賴外圍類的建立。2.它不能使用任何外圍類的非static成員變量和方法。
靜態導包(用來導入類中的靜態資源,1.5以後的新特性):code
- 這兩個關鍵字連用能夠指定導入某個類中的指定靜態資源,而且不須要使用類名調用類中靜態成員,能夠直接使用類中靜態成員變量和成員方法。
static關鍵字的特色對象
- 隨着類的加載而加載
- 優先於對象存在
- 被類的全部對象共享
- 能夠經過類名調用【靜態修飾的內容通常咱們稱其爲:與類相關的,類成員】
static的注意事項生命週期
- 在靜態方法中是沒有this關鍵字的
- 靜態是隨着類的加載而加載,this是隨着對象的建立而存在。
- 靜態比對象先存在。
- 靜態方法只能訪問靜態的成員變量和靜態的成員方法【靜態只能訪問靜態,非靜態能夠訪問靜態的也能夠訪問非靜態的】
2. static變量存儲位置
static變量存儲位置進程
- 注意是:存儲在JVM的方法區中
- static變量在類加載時被初始化,存儲在JVM的方法區中,整個內存中只有一個static變量的拷貝,可使用類名直接訪問,也能夠經過類的實例化對象訪問,通常不推薦經過實例化對象訪問,通俗的講static變量屬於類,不屬於對象,任何實例化的對象訪問的都是同一個static變量,任何地放均可以經過類名來訪問static變量。
3. 用static靜態變量潛在性問題
用static靜態變量潛在性問題內存
- 佔用內存,而且內存通常不會釋放;
- 在系統不夠內存狀況下會自動回收靜態內存,這樣就會引發訪問全局靜態錯誤。
- 在Android中不能將activity做爲static靜態對象,這樣使activity的全部組件對象都存入全局內存中,而且不會被回收;
4. 靜態變量的生命週期
靜態變量的生命週期
- 類在何時被加載?
- 當咱們啓動一個app的時候,系統會建立一個進程,此進程會加載一個Dalvik VM的實例,而後代碼就運行在DVM之上,類的加載和卸載,垃圾回收等事情都由DVM負責。也就是說在進程啓動的時候,類被加載,靜態變量被分配內存。
5. 靜態變量什麼時候銷燬
靜態變量什麼時候銷燬
- 類在何時被卸載?在進程結束的時候。
- 說明:通常狀況下,全部的類都是默認的ClassLoader加載的,只要ClassLoader存在,類就不會被卸載,而默認的ClassLoader生命週期是與進程一致的
6. 靜態引用的對象回收
靜態引用的對象回收
- 只要靜態變量沒有被銷燬也沒有置null,其對象一直被保持引用,也即引用計數不多是0,所以不會被垃圾回收。所以,單例對象在運行時不會被回收
7. 靜態方法變量內存圖
描述Dog對象:
public class Dog {
public static String name;
public static int age;
public static void showNameAge() {
System.out.println("name:" + name + " age:" + age);
}
}
main測試方法:
public class Demo01 {
public static void main(String[] args) {
Dog.name = "阿白";
Dog.age = 98;
Dog.name = "李雙";
Dog.age = 90;
Dog.showNameAge();
}
}
//執行結果:name:李雙 age:90
大概流程就是
- 執行 java Demo01 是給JVM發送指令,和JVM說:把這個 Demo01.class 去執行;
- JVM就去執行 Demo01.class 文件裏面的字節碼,首先第一步 是把 Demo01.class字節碼加載進內存;
- 第二步把Demo01.class放入字節碼存放區;
- 第三步把Demo01裏面的靜態數據(靜態變量 與 靜態方法)分配到 靜態區;
- 第四步main方法進棧,如何進棧的,是把靜態區裏面的main方法拿到運行區(棧) 而後就進棧了;
- 第五步main方法執行 Demo. 的時候,就在此時 才把Dog.class加載進內存;
- 第六步把Dog.class放入字節碼存放區;
- 第七步把Dog裏面的靜態數據(靜態變量 與 靜態方法)分配到 靜態區;
- 第八步 在main方法中執行 Dog.name 是向靜態區去找到 Dog.name 拿來使用,因爲是共享的 name 只保持最後修改的數據;
8. 靜態變量和成員變量的區別
A:所屬不一樣
- 靜態變量屬於類,因此也稱爲類變量
- 成員變量屬於對象,因此也稱爲實例變量(對象變量)
B:內存中位置不一樣
- 靜態變量存儲於方法區的靜態區
- 成員變量存儲於堆內存
C:內存出現時間不一樣
- 靜態變量隨着類的加載而加載,隨着類的消失而消失
- 成員變量隨着對象的建立而存在,隨着對象的消失而消失
D:調用不一樣
- 靜態變量能夠經過類名調用,也能夠經過對象調用
- 成員變量只能經過對象名調用