Java學習中對Static的理解

很多同學學到這裏都會很困惑 很難理解static到底是個什麼?

首先 static是個修飾符被static修飾的變量我們統稱爲靜態變量也叫類變量(爲什麼叫類變量呢 ?因爲我們可以直接使用類來調用被static修飾的變量)

static 不可以修飾局部變量!牢記

再和大家說一下另一種變量,也同樣是成員變量,但是沒有被static修飾,我們叫它全局變量也是很多人嘴裏的動態變量(c中的叫法) 我有個比較更容易的記法,我叫它實例變量,即非靜態變量(對象是類實例化來的大家肯定不陌生 而非static變量想要調用的時候需要用對象丶(點) 所以我稱之爲實例變量)對於靜態變量在內存中只有一個拷貝!JVM只會在加載類時爲靜態分配一次內存,靜態變量是可以通過對象來訪問的。對於非靜態變量!你每new一個實例,JVM中就會爲你分配一次內存,實例變量可以在內存中有多個拷貝,不影響彼此(靈活性)static變量在RAM、ROM中的存儲,存儲在數據存儲區和堆、棧,不是一個存儲區。

插一嘴 講下堆和棧,下面的聽不懂的同學可以先不看

stack 空間小 速度比較快  用來放對象的引用

heap 大 一般所有創建的對象都放在這裏

棧(stack):是一個先進後出的數據結構,通常用於保存方法(c:函數)中的參數、局部變量八種基本類型和自定義對象的引用(c:指針),被執行的方法也會到棧中,執行完會出棧,在java中所有基本類型和引用類型都在棧中存儲,棧中數據的生存空間一般在當前scopes內(就是由{...}括起來的區域)。

堆(heap):是一個可動態申請的內存空間(其記錄空閒內存空間的鏈表由操作系統維護),C中的malloc語句所產生的內存空間就在堆中。

在java中,所有使用new xxx()構造出來的對象都在堆中存儲,當垃圾回收器檢測到某對象未被引用,則自動銷燬該對象。所以,理論上說java中對象的生存空間是沒有限制的,只要有引用類型指向它,則它就可以在任意地方被使用.

1. 棧(stack)與堆(heap)都是Java用來在Ram中存放數據的地方。與C++不同,Java自動管理棧和堆,程序員不能直接地設置棧或堆。

2. 棧的優勢是,存取速度比堆要快,僅次於直接位於CPU中的寄存器。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。另外,棧數據可以共享。
堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,Java的垃圾收集器會自動收走這些不再使用的數據。但缺點是,由於要在運行時動態分配內存,存取速度較慢。

3. Java中的數據類型有兩種。
一種是基本類型(primitive types), 共有8種,即int, short, long, byte, float, double, boolean, char(注意,並沒有string的基本類型)。

這種類型的定義是通過諸如int a = 3; long b = 255L;的形式來定義的,稱爲自動變量。值得注意的是,自動變量存的是字面值,不是類的實例,即不是類的引用,這裏並沒有類的存在。
如int a = 3; 這裏的a是一個指向int類型的引用,指向3這個字面值。這些字面值的數據,由於大小可知,生存期可知(這些字面值固定定義在某個程序塊裏面,程序塊退出後,字段值就消失了),出於追求速度的原因,就存在於棧中。

另外,棧有一個很重要的特殊性,就是存在棧中的數據可以共享。假設我們同時定義:
int a = 3;
int b = 3;

編譯器先處理int a = 3;首先它會在棧中創建一個變量爲a的引用,然後查找有沒有字面值爲3的地址,沒找到,就開闢一個存放3這個字面值的地址,然後將a指向3的地址。接着處理int b = 3;在創建完b的引用變量後,由於在棧中已經有3這個字面值,便將b直接指向3的地址。這樣,就出現了a與b同時均指向3的情況。特別注意的是,這種字面值的引用與類對象的引用不同。
假定兩個類對象的引用同時指向一個對象,如果一個對象引用變量修改了這個對象的內部狀態,那麼另一個對象引用變量也即刻反映出這個變化。

相反,通過字面值的引用來修改其值,不會導致另一個指向此字面值的引用的值也跟着改變的情況。 如上例,我們定義完a與b的值後,再令a=4;

那麼,b不會等於4,還是等於3。在編譯器內部,遇到a=4;時,它就會重新搜索棧中是否有4的字面值,如果沒有,重新開闢地址存放4的值;如果已經有了,則直接將a指向這個地址。
因此a值的改變不會影響到b的值。

另一種是包裝類數據,如Integer, String, Double等將相應的基本數據類型包裝起來的類。這些類數據全部存在於堆中,Java用new()語句來顯示地告訴編譯器,在運行時才根據需要動態創建,因此比較靈活,但缺點是要佔用更多的時間。
4.String是一個特殊的包裝類數據。即可以用String str = new String("abc");的形式來創建,也可以用String str = "abc";的形式來創建(作爲對比,

現在回到我們講的static
static修飾的變量講完了 下面講下static修飾的方法,態方法有什麼好處呢 靜態方法不需要類實例化對象 就可以直接調用
在堆和棧裏面我們說過,對象是個佔用內存相對比較多的東西,也就是說被static修飾過的方法 不再歸對象所有 而是屬於類 當然對象.還是可以調用 這在我看來是不合理的!不推薦使用 推薦直接使用類名調用 如果你看見了一個通過類名直接調用的方法或變量 那麼他一定是static的。

和大家說下static的弊端,static會從你JVM加載類開始 就一直存在 直到整個程序結束纔會釋放!所以請慎用 ! 
static我個人喜歡把他作爲工具來使用,因爲不需要new對象就可以直接用了,例如我們以後要連接數據庫,就可以使用static修飾的方法 因爲連接數據庫並不是某一個對象所特有的,他只是一個工具。

最後給大家講個static修飾的代碼塊,靜態代碼塊和靜態方法的區別在於靜態代碼塊是自動執行的 而方法是你調用他的時候纔會執行靜態方法只能直接調用本類中其他的靜態成員(變量 方法) 靜態無法調用非靜態(先上車後上車)在JVM中被static修飾的會被首先被載入 而這個時候其他未被static修飾的還沒有載入 所以是調用不到的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章