最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java必學必會之static關鍵字

 更新時間:2015年12月03日 14:35:15   作者:孤傲蒼狼  
java必學必會之static關鍵字,static關鍵字是很多朋友在編寫代碼和閱讀代碼時碰到的比較難以理解的一個關鍵字,下面結合大家一起學習static關鍵字

一、static關鍵字

  

  原來一個類里面的成員變量,每new一個對象,這個對象就有一份自己的成員變量,因為這些成員變量都不是靜態(tài)成員變量。對于static成員變量來說,這個成員變量只有一份,而且這一份是這個類所有的對象共享。

1.1.靜態(tài)成員變量與非靜態(tài)成員變量的區(qū)別

  以下面的例子為例說明

package cn.galc.test;

public class Cat {

  /**
   * 靜態(tài)成員變量
   */
  private static int sid = 0;

  private String name;

  int id;

  Cat(String name) {
    this.name = name;
    id = sid++;
  }

  public void info() {
    System.out.println("My Name is " + name + ",NO." + id);
  }

  public static void main(String[] args) {
    Cat.sid = 100;
    Cat mimi = new Cat("mimi");
    Cat pipi = new Cat("pipi");
    mimi.info();
    pipi.info();
  }
}

通過畫內存分析圖了解整個程序的執(zhí)行過程

  執(zhí)行程序的第一句話:Cat.sid = 100;時,這里的sid是一個靜態(tài)成員變量,靜態(tài)變量存放在數(shù)據(jù)區(qū)(data seg),所以首先在數(shù)據(jù)區(qū)里面分配一小塊空間sid,第一句話執(zhí)行完后,sid里面裝著一個值就是100。

  此時的內存布局示意圖如下所示

  

  接下來程序執(zhí)行到:

    Cat  mimi = new Cat(“mimi”);

  這里,調用Cat類的構造方法Cat(String name),構造方法的定義如下:

    Cat ( String name){

      this.name = name;

      id=sid++;

    }

  調用時首先在棧內存里面分配一小塊內存mm,里面裝著可以找到在堆內存里面的Cat類的實例對象的地址,mm就是堆內存里面Cat類對象的引用對象。這個構造方法聲明有字符串類型的形參變量,所以這里把“mimi”作為實參傳遞到構造方法里面,由于字符串常量是分配在數(shù)據(jù)區(qū)存儲的,所以數(shù)據(jù)區(qū)里面多了一小塊內存用來存儲字符串“mimi”。此時的內存分布如下圖所示:

  

  當調用構造方法時,首先在棧內存里面給形參name分配一小塊空間,名字叫name,接下來把”mimi”這個字符串作為實參傳遞給name,字符串也是一種引用類型,除了那四類8種基礎數(shù)據(jù)類型之外,其他所有的都是引用類型,所以可以認為字符串也是一個對象。所以這里相當于把”mimi”這個對象的引用傳遞給了name,所以現(xiàn)在name指向的是”mimi”。所以此時內存的布局如下圖所示:

  接下來執(zhí)行構造方法體里面的代碼:

    this.name=name;

  這里的this指的是當前的對象,指的是堆內存里面的那只貓。這里把棧里面的name里面裝著的值傳遞給堆內存里面的cat對象的name屬性,所以此時這個name里面裝著的值也是可以找到位于數(shù)據(jù)區(qū)里面的字符串對象“mimi”的,此時這個name也是字符串對象“mimi”的一個引用對象,通過它的屬性值就可以找到位于數(shù)據(jù)區(qū)里面的字符串對象“mimi”。此時的內存分布如下圖所示:

  

  接下來執(zhí)行方法體內的另一句代碼:id=sid++;

  這里是把sid的值傳遞給id,所以id的值是100,sid傳遞完以后,自己再加1,此時sid變成了101。此時的內存布局如下圖所示。

  

  到此,構造方法調用完畢,給這個構造方法分配的局部變量所占的內存空間全部都要消失,所以位于??臻g里面的name這塊內存消失了。棧內存里面指向數(shù)據(jù)區(qū)里面的字符串對象“mimi”的引用也消失了,此時只剩下堆內存里面的指向字符串對象“mimi”的引用沒有消失。此時的內存布局如下圖所示:

  

  接下來執(zhí)行:Cat  pipi = new Cat(“pipi”);

  這里是第二次調用構造方法Cat(),整個調用過程與第一次一樣,調用結束后,此時的內存布局如下圖所示:

  

  最后兩句代碼是調用info()方法打印出來,打印結果如下:

  

  通過這個程序,看出來了這個靜態(tài)成員變量sid的作用,它可以計數(shù)。每當有一只貓new出來的時候,就給它記一個數(shù)。讓它自己往上加1。

  程序執(zhí)行完后,內存中的整個布局就如上圖所示了。一直持續(xù)到main方法調用完成的前一刻。

  這里調用構造方法Cat(String name) 創(chuàng)建出兩只貓,首先在棧內存里面分配兩小塊空間mimi和pipi,里面分別裝著可以找到這兩只貓的地址,mimi和pipi對應著堆內存里面的兩只貓的引用。這里的構造方法聲明有字符串類型的變量,字符串常量是分配在數(shù)據(jù)區(qū)里面的,所以這里會把傳過來的字符串mimi和pipi都存儲到數(shù)據(jù)區(qū)里面。所以數(shù)據(jù)區(qū)里面分配有存儲字符串mimi和pipi的兩小塊內存,里面裝著字符串“mimi”和“pipi”,字符串也是引用類型,除了那四類8種的基礎數(shù)據(jù)類型之外,其他所有的數(shù)據(jù)類型都是引用類型。所以可以認為字符串也是一個對象。

  這里是new了兩只貓出來,這兩只貓都有自己的id和name屬性,所以這里的id和name都是非靜態(tài)成員變量,即沒有static修飾。所以每new出一只新貓,這只新貓都有屬于它自己的id和name,即非靜態(tài)成員變量id和name是每一個對象都有單獨的一份。但對于靜態(tài)成員變量來說,只有一份,不管new了多少個對象,哪怕不new對象,靜態(tài)成員變量在數(shù)據(jù)區(qū)也會保留一份。如這里的sid一樣,sid存放在數(shù)據(jù)區(qū),無論new出來了多少只貓在堆內存里面,sid都只有一份,只在數(shù)據(jù)區(qū)保留一份。

  靜態(tài)成員變量是屬于整個類的,它不屬于專門的某個對象。那么如何訪問這個靜態(tài)成員變量的值呢?首先第一點,任何一個對象都可以訪問這個靜態(tài)的值,訪問的時候訪問的都是同一塊內存。第二點,即便是沒有對象也可以訪問這個靜態(tài)的值,通過“類名.靜態(tài)成員變量名”來訪問這個靜態(tài)的值,所以以后看到某一個類名加上“.”再加上后面有一個東西,那么后面這個東西一定是靜態(tài)的,如”System.out”,這里就是通過類名(System類)再加上“.”來訪問這個out的,所以這個out一定是靜態(tài)的。

再看下面的這段代碼

package cn.galc.test;

public class Cat {

  /**
   * 這里面的sid不再是靜態(tài)成員變量了,因為沒有static修飾符,
   * 此時它就是類里面一個普通的非靜態(tài)成員變量,和id,name一樣,
   * 成為每一個new出來的對象都具有的屬性。
   */
  private int sid = 0;

  private String name;

  int id;

  Cat(String name) {
    this.name = name;
    id = sid++;
  }

  public void info() {
    System.out.println("My Name is " + name + ",NO." + id);
  }

  public static void main(String[] args) {
    //Cat.sid = 100;這里不能再使用“類.靜態(tài)成員變量”的格式來訪問sid了,因為sid現(xiàn)在變成了非靜態(tài)的成員變量了。所以必須要把這句話注釋掉,否則無法編譯通過。
    Cat mimi = new Cat("mimi");
    Cat pipi = new Cat("pipi");
    mimi.info();
    pipi.info();
  }
}

  這段代碼與上一段代碼唯一的區(qū)別是把聲明sid變量的static修飾符給去掉了,此時的sid就不再是靜態(tài)成員變量,而是非靜態(tài)成員變量了,此時每一個new出來的cat對象都會有自己單獨的sid屬性。所以這段代碼執(zhí)行完成后,內存中的布局如下圖所示:

  

  由于sid變成了非靜態(tài)成員變量,所以不再有計數(shù)的功能了。sid與id和name屬性一樣,成為每一個new出來的對象都具有的屬性,所以每一個new出來的cat都加上了一個sid屬性。由于不能再使用”類名.靜態(tài)成員對象名”的格式訪問sid,所以代碼的第一句”Cat.sid =100;”不能這樣使用,否則編譯會出錯,必須把這句話注釋掉才能編譯成功。既然無法訪問得到sid的值,所以sid的值就一直都是初始化時賦給的值0。直到調用構造方法時,執(zhí)行到方法體內的代碼id=sid++;時,sid首先把自身的值0賦值給id,所以id的值是0,然后sid自己加1,所以sid變成了1。

  所以靜態(tài)變量和非靜態(tài)變量的區(qū)別就在于靜態(tài)變量可以用來計數(shù),而非靜態(tài)變量則不行。

  理解了內存,就理解了一切,就理解了各種各樣的語言。所有的語言無非都是這樣:局部變量分配內存永遠在棧里面,new出來的東西分配內存永遠是在堆里,靜態(tài)的東西分配內存永遠是在數(shù)據(jù)區(qū)。剩下的代碼肯定是在代碼區(qū)。所有的語言都是這樣。

  在一個靜態(tài)方法里,如果想訪問一個非靜態(tài)的成員變量,是不能直接訪問的,必須在靜態(tài)方法里new一個對象出來才能訪問。如果是加了static的成員變量,那么這個成員變量就是一個靜態(tài)的成員變量,就可以在main方法里面直接訪問了。

  main方法是一個靜態(tài)的方法,main方法要執(zhí)行的時候不需要new一個對象出來。

  動態(tài)方法是針對于某一個對象調用的,靜態(tài)方法不會針對某一個對象來調用,沒有對象照樣可以用。所以可以使用”classname.method()”.的形式來調用靜態(tài)方法。所以想在main方法里面訪問非靜態(tài)成員變量是不可以的,想在main方法里面訪問非靜態(tài)方法也是不可以的,因為非靜態(tài)方法只能針對于某個對象來調用,沒有對象,就找不到方法的執(zhí)行者了。

  成員變量只有在new出一個對象來的時候才在堆內存里面分配存儲空間。局部變量在棧內存里面分配存儲空間。

  靜態(tài)方法不再是針對某一個對象來調用,所以不能訪問非靜態(tài)的成員。

  非靜態(tài)成員專屬于某一個對象,想訪問非靜態(tài)成員必須new一個對象出來才能訪問。

  靜態(tài)的變量可以通過對象名去訪問,也可以通過類名去訪問,兩者訪問的都是同一塊內存。

以上就是本文的全部內容,信息量很大,需要大家耐心閱讀,從而真正的學會java static關鍵字。

相關文章

  • Javasript設計模式之鏈式調用詳解

    Javasript設計模式之鏈式調用詳解

    這篇文章主要為大家詳細介紹了Javasript設計模式之鏈式調用的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • js 原型對象和原型鏈理解

    js 原型對象和原型鏈理解

    本文主要介紹了js原型對象和原型鏈的相關知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • 通過js控制時間,一秒一秒自己動的實例

    通過js控制時間,一秒一秒自己動的實例

    下面小編就為大家?guī)硪黄ㄟ^js控制時間,一秒一秒自己動的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • js removeChild 障眼法 可能出現(xiàn)的錯誤

    js removeChild 障眼法 可能出現(xiàn)的錯誤

    js removeChild 障眼法之可能出現(xiàn)的錯誤,大家看下代碼就知道了。
    2009-10-10
  • JavaScript數(shù)組去重的幾種方法效率測試

    JavaScript數(shù)組去重的幾種方法效率測試

    JavaScript數(shù)組去重是前端面試酷愛的問題,問題簡單而又能看出程序員對計算機程序執(zhí)行過程的理解如何。數(shù)組去重的方法有很多,到底哪種是最理想的我不清楚。于是我測試了下數(shù)組去重的效率。測試二十萬個數(shù)據(jù),隨著數(shù)據(jù)越多效率很明顯的就體驗了出來。下面來一起看看吧。
    2016-10-10
  • javascript簡單計算器 可美化

    javascript簡單計算器 可美化

    javascript簡單計算器 可美化,需要的朋友可以測試下。參考下實現(xiàn)原理。
    2011-10-10
  • JavaScript 正則表達式中global模式的特性

    JavaScript 正則表達式中global模式的特性

    這篇文章主要介紹了JavaScript 正則表達式中global模式的特性 的相關資料,需要的朋友可以參考下
    2016-02-02
  • js 排序動畫模擬 冒泡排序

    js 排序動畫模擬 冒泡排序

    在js中,想讓線程sleep一下確實不是一件簡單的事情,過多的使用定時器或者回調函數(shù),會讓復雜,凌亂,這時,可以考慮能否使用隊列來做一些簡
    2012-07-07
  • js出生日期 年月日級聯(lián)菜單示例代碼

    js出生日期 年月日級聯(lián)菜單示例代碼

    本篇文章主要介紹了js出生日期 年月日級聯(lián)菜單的示例代碼。需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • js數(shù)組forEach實例用法詳解

    js數(shù)組forEach實例用法詳解

    在本篇文章里小編給大家整理了一篇關于js數(shù)組forEach實例用法詳解內容,有需要的朋友們可以跟著學習參考下。
    2021-10-10

最新評論

霍林郭勒市| 长寿区| 赤峰市| 甘谷县| 和平县| 陇西县| 巧家县| 长汀县| 辉县市| 珲春市| 仁布县| 孟州市| 屏东市| 繁峙县| 会同县| 东莞市| 清水河县| 米脂县| 巴彦淖尔市| 英吉沙县| 昂仁县| 响水县| 濮阳市| 醴陵市| 老河口市| 钟山县| 冕宁县| 鄯善县| 定结县| 梓潼县| 遵化市| 鹿邑县| 贵南县| 来宾市| 乌审旗| 北海市| 武定县| 沈丘县| 城固县| 泉州市| 霍山县|