亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

從內(nèi)存地址解析Java的static關(guān)鍵字的作用

 更新時(shí)間:2015年10月30日 09:00:42   作者:孤傲蒼狼  
這篇文章主要介紹了從內(nèi)存地址解析Java的static關(guān)鍵字的作用,包括靜態(tài)成員變量和靜態(tài)方法等重要內(nèi)容,需要的朋友可以參考下

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

  以下面的例子為例說(shuō)明

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();
  }
}

通過(guò)畫(huà)內(nèi)存分析圖了解整個(gè)程序的執(zhí)行過(guò)程

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

  此時(shí)的內(nèi)存布局示意圖如下所示

2015103085457947.png (497×296)

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

    Cat mimi = new Cat(“mimi”);

  這里,調(diào)用Cat類的構(gòu)造方法Cat(String name),構(gòu)造方法的定義如下:

    Cat ( String name){

      this.name = name;

      id=sid++;

    }

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

2015103085520724.png (500×298)

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

2015103085536595.png (498×296)

接下來(lái)執(zhí)行構(gòu)造方法體里面的代碼:

    this.name=name;

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

2015103085553096.png (497×297)

接下來(lái)執(zhí)行方法體內(nèi)的另一句代碼:

    id=sid++;

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

2015103085614750.png (497×297)

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

2015103085633187.png (497×296)

接下來(lái)執(zhí)行:

Cat pipi = new Cat(“pipi”);

  這里是第二次調(diào)用構(gòu)造方法Cat(),整個(gè)調(diào)用過(guò)程與第一次一樣,調(diào)用結(jié)束后,此時(shí)的內(nèi)存布局如下圖所示:

2015103085650357.png (498×297)

最后兩句代碼是調(diào)用info()方法打印出來(lái),打印結(jié)果如下:

  

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

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

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

  這里是new了兩只貓出來(lái),這兩只貓都有自己的id和name屬性,所以這里的id和name都是非靜態(tài)成員變量,即沒(méi)有static修飾。所以每new出一只新貓,這只新貓都有屬于它自己的id和name,即非靜態(tài)成員變量id和name是每一個(gè)對(duì)象都有單獨(dú)的一份。但對(duì)于靜態(tài)成員變量來(lái)說(shuō),只有一份,不管new了多少個(gè)對(duì)象,哪怕不new對(duì)象,靜態(tài)成員變量在數(shù)據(jù)區(qū)也會(huì)保留一份。如這里的sid一樣,sid存放在數(shù)據(jù)區(qū),無(wú)論new出來(lái)了多少只貓?jiān)诙褍?nèi)存里面,sid都只有一份,只在數(shù)據(jù)區(qū)保留一份。

  靜態(tài)成員變量是屬于整個(gè)類的,它不屬于專門的某個(gè)對(duì)象。那么如何訪問(wèn)這個(gè)靜態(tài)成員變量的值呢?首先第一點(diǎn),任何一個(gè)對(duì)象都可以訪問(wèn)這個(gè)靜態(tài)的值,訪問(wèn)的時(shí)候訪問(wèn)的都是同一塊內(nèi)存。第二點(diǎn),即便是沒(méi)有對(duì)象也可以訪問(wèn)這個(gè)靜態(tài)的值,通過(guò)“類名.靜態(tài)成員變量名”來(lái)訪問(wèn)這個(gè)靜態(tài)的值,所以以后看到某一個(gè)類名加上“.”再加上后面有一個(gè)東西,那么后面這個(gè)東西一定是靜態(tài)的,如”System.out”,這里就是通過(guò)類名(System類)再加上“.”來(lái)訪問(wèn)這個(gè)out的,所以這個(gè)out一定是靜態(tài)的。
如果一個(gè)類成員被聲明為static,它就能夠在類的任何對(duì)象創(chuàng)建之前被訪問(wèn),而不必引用任何對(duì)象。static 成員的最常見(jiàn)的例子是main( ) 。因?yàn)樵诔绦蜷_(kāi)始執(zhí)行時(shí)必須調(diào)用main() ,所以它被聲明為static。
聲明為static的變量實(shí)質(zhì)上就是全局變量。當(dāng)聲明一個(gè)對(duì)象時(shí),并不產(chǎn)生static變量的拷貝,而是該類所有的實(shí)例變量共用同一個(gè)static變量,例如:聲明一個(gè)static的變量count作為new一個(gè)類實(shí)例的計(jì)數(shù)。聲明為static的方法有以下幾條限制:
(1)、它們僅能調(diào)用其他的static 方法。
(2)、它們只能訪問(wèn)static數(shù)據(jù)。
(3)、它們不能以任何方式引用this 或super。
如果你需要通過(guò)計(jì)算來(lái)初始化你的static變量,你可以聲明一個(gè)static塊,Static 塊僅在該類被加載時(shí)執(zhí)行一次。下面的例子顯示

的類有一個(gè)static方法,一些static變量,以及一個(gè)static 初始化塊:
public class UserStatic { 
    static int a = 3; 
    static int b;  
    static void meth(int x) { 
      System.out.println("x = " + x); 
      System.out.println("a = " + a); 
      System.out.println("b = " + b);  
    }  
    static { 
      System.out.println("Static block initialized."); 
      b = a * 4;  
    }  
    public static void main(String args[]) { 
      meth(42);  
    } 
  }

一旦UseStatic 類被裝載,所有的static語(yǔ)句被運(yùn)行。首先,a被設(shè)置為3,接著static 塊執(zhí)行(打印一條消息),最后,b被初始化為a*4 或12。然后調(diào)用main(),main() 調(diào)用meth() ,把值42傳遞給x。3個(gè)println ( ) 語(yǔ)句引用兩個(gè)static變量a和b,以及局部變量x 。
注意:在一個(gè)static 方法中引用任何實(shí)例變量都是非法的。
下面是該程序的輸出:

Static block initialized. 
x = 42 
a = 3 
b = 12

在定義它們的類的外面,static 方法和變量能獨(dú)立于任何對(duì)象而被使用。這樣,你只要在類的名字后面加點(diǎn)號(hào)(.)運(yùn)算符即可。例如,如果你希望從類外面調(diào)用一個(gè)static方法,你可以使用下面通用的格式:
classname.method( )
這里,classname 是類的名字,在該類中定義static方法??梢钥吹剑@種格式與通過(guò)對(duì)象引用變量調(diào)用非static方法的格式類似。一個(gè)static變量可以以同樣的格式來(lái)訪問(wèn)——類名加點(diǎn)號(hào)運(yùn)算符。這就是Java 如何實(shí)現(xiàn)全局功能和全局變量的一個(gè)控制版本。
總結(jié):
(1)、static成員是不能被其所在class創(chuàng)建的實(shí)例訪問(wèn)的。
(2)、如果不加static修飾的成員是對(duì)象成員,也就是歸每個(gè)對(duì)象所有的。
(3)、加static修飾的成員是類成員,就是可以由一個(gè)類直接調(diào)用,為所有對(duì)象共有的。
 
 
Java Static:作為修飾符, 可以用來(lái)修飾變量、方法、代碼塊(但絕對(duì)不能修飾類)。

(1)、修飾變量:
類的所有對(duì)象共同擁有的一個(gè)屬性,也稱為類變量。這類似于C語(yǔ)言中的全局變量。類變量在類加載的時(shí)候初始化,而且只被初始化一次。在程序中任何對(duì)象對(duì)靜態(tài)變量做修改,其他對(duì)象看到的是修改后的值。因此類變量可以用作計(jì)數(shù)器。另外,Java Static變量可以用類名直接訪問(wèn),而不必需要對(duì)象。
(2)、修飾方法:
類的所有對(duì)象共同擁有的一個(gè)功能,稱為靜態(tài)方法。靜態(tài)方法也可以用類名直接訪問(wèn),而不必需要對(duì)象。所以在靜態(tài)方法里不能直接訪問(wèn)非靜態(tài)變量和非靜態(tài)方法,在Static方法里不能出現(xiàn)this或者super等關(guān)鍵字。
(3)、修飾Java代碼塊:
用static去修飾類里面的一個(gè)獨(dú)立的代碼塊,稱為靜態(tài)代碼塊。靜態(tài)代碼塊在類第一次被加載的時(shí)候執(zhí)行,而且只執(zhí)行一次。靜態(tài)代碼塊沒(méi)有名字,因此不能顯式調(diào)用,而只有在類加載的時(shí)候由虛擬機(jī)來(lái)調(diào)用。它主要用來(lái)完成一些初始化操作。
(4)、說(shuō)說(shuō)類加載:
JVM在第一次使用一個(gè)類時(shí),會(huì)到classpath所指定的路徑里去找這個(gè)類所對(duì)應(yīng)的字節(jié)碼文件, 并讀進(jìn)JVM保存起來(lái),這個(gè)過(guò)程稱之為類加載。
可見(jiàn),無(wú)論是變量,方法,還是代碼塊,只要用static修飾,就是在類被加載時(shí)就已經(jīng)"準(zhǔn)備好了",也就是可以被使用或者已經(jīng)被執(zhí)行。都可以脫離對(duì)象而執(zhí)行。反之,如果沒(méi)有static,則必須通過(guò)對(duì)象來(lái)訪問(wèn)。

相關(guān)文章

  • spring在IoC容器中裝配Bean詳解

    spring在IoC容器中裝配Bean詳解

    這篇文章主要介紹了spring在IoC容器中裝配Bean詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2017-12-12
  • 詳解Java中的File文件類以及FileDescriptor文件描述類

    詳解Java中的File文件類以及FileDescriptor文件描述類

    在Java中File類可以用來(lái)新建文件和目錄對(duì)象,而FileDescriptor類則被用來(lái)表示文件或目錄的可操作性,接下來(lái)我們就來(lái)詳解Java中的File文件類以及FileDescriptor文件描述類
    2016-06-06
  • 詳解如何配置Spring Batch批處理失敗重試機(jī)制

    詳解如何配置Spring Batch批處理失敗重試機(jī)制

    這篇文章主要來(lái)和大家一起探討一下如何在Spring批處理框架中配置重試邏輯,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-06-06
  • Java?Unsafe創(chuàng)建對(duì)象的方法實(shí)現(xiàn)

    Java?Unsafe創(chuàng)建對(duì)象的方法實(shí)現(xiàn)

    Java中使用Unsafe實(shí)例化對(duì)象是一項(xiàng)十分有趣而且強(qiáng)大的功能,本文主要介紹了Java?Unsafe創(chuàng)建對(duì)象的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Java?Stream常用方法合集(超詳細(xì))

    Java?Stream常用方法合集(超詳細(xì))

    Stream?API?提供了一種更為簡(jiǎn)潔高效的的方式來(lái)處理集合數(shù)據(jù),??可讀性較高,?所以本文為大家整理了Java?Stream中的常用方法,希望對(duì)大家有所幫助
    2023-07-07
  • MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法詳解

    MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法詳解

    這篇文章主要介紹了MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2019-07-07
  • Maven優(yōu)雅的添加第三方Jar包的方法

    Maven優(yōu)雅的添加第三方Jar包的方法

    下面小編就為大家?guī)?lái)一篇Maven優(yōu)雅的添加第三方Jar包的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • java的IO流詳細(xì)解讀

    java的IO流詳細(xì)解讀

    這篇文章主要介紹了java的IO流詳細(xì)解讀,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • SpringBoot 插件化開(kāi)發(fā)模式詳細(xì)總結(jié)

    SpringBoot 插件化開(kāi)發(fā)模式詳細(xì)總結(jié)

    插件化開(kāi)發(fā)模式正在很多編程語(yǔ)言或技術(shù)框架中得以廣泛的應(yīng)用實(shí)踐,大大提升了系統(tǒng)的擴(kuò)展性和伸縮性,也拓展了系統(tǒng)整體的使用價(jià)值,那么為什么要使用插件呢,本文就詳細(xì)介紹SpringBoot 插件化開(kāi)發(fā)模式,感興趣的同學(xué)可以參考下
    2023-06-06
  • JAVA爬蟲(chóng)實(shí)現(xiàn)自動(dòng)登錄淘寶

    JAVA爬蟲(chóng)實(shí)現(xiàn)自動(dòng)登錄淘寶

    給大家分享一個(gè)關(guān)于JAVA爬蟲(chóng)的相關(guān)知識(shí)點(diǎn),通過(guò)代碼實(shí)現(xiàn)自動(dòng)登錄淘寶網(wǎng),有興趣的朋友測(cè)試下。
    2018-04-04

最新評(píng)論