java基礎_面向對象_static關鍵字

    一直感覺對靜態的理解不到位,知道修飾類的屬性和方法、修飾代碼塊(不能修飾普通類但是可以修飾內部類)。在合適的環境下,提高程序的運行性能,優化程序的結構;反之,不合理的運用因爲難以被GC掉,構成內存負擔造成內存溢出,在android開發中尤爲明顯,有些閃退就是因爲out of memory。

   再去重新理解static的時候我想從最簡單的開始,修飾類的屬性。

目錄


(1) 修飾類的屬性

   在類中,static修飾的成員變量稱爲靜態成員變量,它爲該類的公有變量,只有在第一次使用時被初始化,對於該類所有對象來說,static成員變量只有一份。

    靜態成員變量是屬於整個類的,不屬於具體的某個對象。那麼對這個靜態的值怎麼訪問呢?首先,任何一個對象都可以訪問這個靜態的值,訪問的時候都是訪問的同一塊內存 。其次,即便是沒有對象,你也可以類名.訪問這個值。

    舉個簡單的列子,猜一下輸出的結果,然後內存上分析咋回事。

public class Test {
    public static void main(String[] args) {
        Cat.sid = 100;
        Cat cat1 = new Cat();
        Cat cat2 = new Cat();

        cat1.info();
        cat2.info();
    }
}
public class Cat {
    static int sid;
    int id;

    public Cat() {
        id = sid++;
    }

    public void info() {
        System.out.println("static cat:" + "sid=" + sid + "  id=" + id);
    }
}

顯然定義了static int sid,結果:挺有意思。

static cat:sid=102  id=100
static cat:sid=102  id=101

加載過程,JVM內存分四種:

  1. 棧區(stack segment)- 由編譯器自動分配釋放,存放函數的參數值,局部變量的值等,具體方法執行結束之後,系統自動釋放JVM內存資源。
  2. 堆區(heapsegment)- 存放new出來的對象和數組,jvm不定時查看這個對象,如果沒有引用指向這個對象就回收掉。
  3. 方法區(也叫:數據區,共享區,共享數據區) - 存放全局變量,靜態變量和字符串常量,和方法。
  4. 代碼區(codesegment) - 存放程序中方法的二進制代碼,而且是多個對象共享一個代碼空間區域。

因此首先Cat.sid = 100;數據區中專門分配一小塊位置存放。
其次Cat cat1 = new Cat();位置棧空間中分配一塊名爲cat1,值是指向另一大塊內存的地址;堆空間中分配一大塊內存用於new出來的對象,其中對象的屬性id被賦值爲100;id = sid++; sid++後爲101;同理cat2時,此時sid=101,cat2的id值被賦予101,然後sid爲102;

這裏寫圖片描述

以上也就說明了靜態成員變量是屬於整個類的,不屬於具體的某個對象。

那麼我們試着把static int sid; 改爲非靜態int sid; 最後輸出:

non static cat:sid=1  id=0
non static cat:sid=1  id=0

(2) 修飾類的方法

   用static聲明的方法爲靜態方法,在調用該方法時,不會將對象的引用傳遞給它,所以在static方法中不可以訪問非static的成員。
   動態方法是針對於某一個對象進行調用的。靜態的方法呢?它不針對某一個對象,和靜態成員變量一樣是屬於整個類的,沒有對象照樣可以調用,就像Cat.靜態方法。也正因爲如此靜態方法中不能訪問非static的成員和非靜態的方法,比如在main方法中id=9會報錯的。
   在工具類中常會有修飾方法,方便調用,免去new對象這個繁瑣的過程。比如:TextUtils.isEmpty(string) 源碼

     public static boolean isEmpty(@Nullable CharSequence str) {
        if (str == null || str.length() == 0)
            return true;
        else
            return false;
    }

(3) 修飾代碼塊

   靜態代碼塊一般和類的加載相關,可以將多個類成員放在一起初始化。


   常見提示錯誤: 無法從靜態上下文中引用非靜態 變量 this

   this 是指向當前對象的引用,需要對象實例化以後才能賦值。而靜態成員都是類所屬的,不需要對實例化就可以使用,所以在靜態上下文中引用this時可能其還未賦值,所以應不能這樣使用。

   在靜態方法內只能引用靜態變量

關於static簡單的入門級總結就是以上這些,如有疑問或者質疑煩勞留言或私信。

“愛情來得快 去得也快 只有豬肉卷是永恆的” –加菲貓。
同理“愛情來得快 去得也快 只有java是永恆的”。

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