Java基礎學習總結(10)——static關鍵字

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

一、static關鍵字

  

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

1.1.靜態成員變量與非靜態成員變量的區別

  以下面的例子為例說明

復制代碼
 1 package cn.galc.test;
 2 
 3 public class Cat {
 4 
 5     /**
 6      * 靜態成員變量
 7      */
 8     private static int sid = 0;
 9 
10     private String name;
11 
12     int id;
13 
14     Cat(String name) {
15         this.name = name;
16         id = sid++;
17     }
18 
19     public void info() {
20         System.out.println("My Name is " + name + ",NO." + id);
21     }
22 
23     public static void main(String[] args) {
24         Cat.sid = 100;
25         Cat mimi = new Cat("mimi");
26         Cat pipi = new Cat("pipi");
27         mimi.info();
28         pipi.info();
29     }
30 }
復制代碼

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

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

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

  

  接下來程序執行到:

    Cat??mimi?=?new?Cat(“mimi”);

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

    Cat?(?String?name){

      this.name?=?name;

      id=sid++;

    }

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

  

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

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

    this.name=name;

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

  

  接下來執行方法體內的另一句代碼:

    id=sid++;

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

  

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

  

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

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

  

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

  

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

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

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

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

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

再看下面的這段代碼

復制代碼
 1 package cn.galc.test;
 2 
 3 public class Cat {
 4 
 5     /**
 6      * 這里面的sid不再是靜態成員變量了,因為沒有static修飾符,
 7      * 此時它就是類里面一個普通的非靜態成員變量,和id,name一樣,
 8      * 成為每一個new出來的對象都具有的屬性。
 9      */
10     private  int sid = 0;
11 
12     private String name;
13 
14     int id;
15 
16     Cat(String name) {
17         this.name = name;
18         id = sid++;
19     }
20 
21     public void info() {
22         System.out.println("My Name is " + name + ",NO." + id);
23     }
24 
25     public static void main(String[] args) {
26         //Cat.sid = 100;這里不能再使用“類.靜態成員變量”的格式來訪問sid了,因為sid現在變成了非靜態的成員變量了。所以必須要把這句話注釋掉,否則無法編譯通過。
27         Cat mimi = new Cat("mimi");
28         Cat pipi = new Cat("pipi");
29         mimi.info();
30         pipi.info();
31     }
32 }
復制代碼

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

  

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

  所以靜態變量和非靜態變量的區別就在于靜態變量可以用來計數,而非靜態變量則不行。

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

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

  main方法是一個靜態的方法,main方法要執行的時候不需要new一個對象出來。

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

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

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

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

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

轉載于:https://my.oschina.net/zhanghaiyang/blog/594766

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/536378.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536378.shtml
英文地址,請注明出處:http://en.pswp.cn/news/536378.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ActiveMQ學習總結(3)——spring整合ActiveMQ

2019獨角獸企業重金招聘Python工程師標準>>> 1.參考文獻 Spring集成ActiveMQ配置Spring JMS異步發收消息 ActiveMQ2.環境 在前面的一篇 ActiveMQ入門實例中我們實現了消息的異步傳送,這篇博文將如何在spring環境下集成ActiveMQ。如果要在spring下集成Act…

Pots【廣搜,模擬】

Pots POJ - 3414 You are given two pots, having the volume of A and B liters respectively. The following operations can be performed: FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;DROP(i) empty the pot i to the drain;POUR(i,j) pour fro…

非常可樂【廣搜,模擬】

非常可樂 HDU - 1495 大家一定覺的運動以后喝可樂是一件很愜意的事情,但是seeyou卻不這么認為。因為每次當seeyou買了可樂以后,阿牛就要求和seeyou一起分享這一瓶可樂,而且一定要喝的和seeyou一樣多。但seeyou的手中只有兩個杯子&#xff0…

問題 A: 深度學習

問題 A: 深度學習 時間限制: 1 Sec 內存限制: 128 MB 提交: 53 解決: 42 [提交] [狀態] [討論版] [命題人:admin] 題目描述 小 A 最近在研究深度學習,他自己搭建了一個很牛逼的神經網絡,現在他手頭一共有 n 組訓練數據,一開始他會給自己的…

堆樹

一、堆樹的定義 堆樹的定義如下: (1)堆樹是一顆完全二叉樹; (2)堆樹中某個節點的值總是不大于或不小于其孩子節點的值; (3)堆樹中每個節點的子樹都是堆樹。 當父節點的鍵…

問題 D: 最小生成樹II

問題 D: 最小生成樹II 時間限制: 1 Sec 內存限制: 128 MB 提交: 89 解決: 44 [提交] [狀態] [討論版] [命題人:admin] 題目描述 小A有一張n個點的帶權無向圖,這張無向圖非常特別,首先第i個點有一個點權ai,之后這張無向圖是一張完全圖&…

問題 G: 區間權值

問題 G: 區間權值 時間限制: 1 Sec 內存限制: 128 MB 提交: 112 解決: 49 [提交] [狀態] [討論版] [命題人:admin] 題目描述 小Bo有n個正整數a1..an,以及一個權值序列w1…wn,現在他定義 現在他想知道的值,需要你來幫幫他 你只需要輸出答案…

問題 I: 連通塊計數

問題 I: 連通塊計數 時間限制: 1 Sec 內存限制: 128 MB 提交: 108 解決: 45 [提交] [狀態] [討論版] [命題人:admin] 題目描述 小A有一棵長的很奇怪的樹,他由n條鏈和1個點作為根構成,第i條鏈有ai個點,每一條鏈的一端都與根結點相連。 現在…

telnet 功能啟用并測試端口是否正常

記錄日期:2019年6月21日 13點52分 操作系統:Windows 10 由于 Ping命令可以檢查網絡是否連通,但無法準確判斷某個端口是否連通,因此需要使用 Telnet協議。 1、打開控制面板中的程序和功能。 2、側邊欄,啟用或關閉Window…

步步為營 SharePoint 開發學習筆記系列 七、SharePoint Timer Job 開發

概要 項目需求要求我們每天晚上同步員工的一些信息到sharepoint 的user List ,我們決定定制開發sharepoint timer Job,Sharepoint timer Job是sharePoint的定時作業Job,需要安裝、布曙到服務器上,而這里我只是介紹下Job開發的例子,以供大家學習用。 開發…

問題 J: 尋找復讀機【模擬】

問題 J: 尋找復讀機 時間限制: 1 Sec 內存限制: 128 MB 提交: 131 解決: 50 [提交] [狀態] [討論版] [命題人:admin] 題目描述 某個QQ群里一共有n個人,他們的編號是1..n,其中有一些人本質上是復讀機。 小A發現,如果一個人的本質是復讀機&…

windows下jenkins常見問題填坑

沒有什么高深的東西,1 2天的時間大多數人都能自己摸索出來,這里將自己遇到過的問題分享出來避免其他同學再一次挖坑. 目錄 1. 主從節點 2. Nuget自動包還原 3. powershell部署 4. 內網機器實現基于變化的構建 5. Github私有項目pull時限 所謂主從&#x…

Cow Contest【最短路-floyd】

Cow Contest POJ - 3660 N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the competitors. …

【學習Android NDK開發】Type Signatures(類型簽名)

類型簽名&#xff08;Type Signatures&#xff09; (<Parameter 1 Type Code>[<Parameter 1 Class>];...)<Return Type Code> The JNI uses the Java VM’s representation of type signatures. Following Table shows these type signatures. Type Signatur…

Symantec(賽門鐵克)非受管檢測

為了查找局域網內沒有安裝賽門鐵克客戶端的IP&#xff0c;采用Symantec Endpoint Protect Manager 的非受管檢測機制進行網段掃描。 非受管檢測機制的原理是&#xff1a;每臺電腦開機時都會向同網段電腦發arp&#xff0c;當非受管檢測器接到arp請求時&#xff0c;會寫入本地的a…

SQL語句性能優化操作

1、對查詢進行優化&#xff0c;應盡量避免全表掃描&#xff0c;首先應考慮在where及order by涉及的列上建立索引。 2、應盡量避免在where子句中對字段進行null值判斷&#xff0c;創建表時NULL是默認值&#xff0c;但大多數時候應該使用NOT NULL&#xff0c;或者使用一個特殊的值…

sql語言特殊字符處理

我們都知道SQL Server查詢過程中&#xff0c;單引號“”是特殊字符&#xff0c;所以在查詢的時候要轉換成雙單引號“”。但這只是特殊字符的一個&#xff0c;在實際項目中&#xff0c;發現對于like操作還有以下特殊字符&#xff1a;下劃線“_”&#xff0c;百分號“%”&#xf…

小節

算法導論已學兩部分&#xff0c;第一部分是基礎知識&#xff0c;第二部分是排序。基礎知識介紹如何分析證明算法以及求時間復雜度。第二部分的排序學了很長時間。先是從簡單排序到復雜排序的一個過渡&#xff0c;打開了很多思路。然后就是無盡的算法分析。算法分析的時間比理解…

SPS2003升級到MOSS2007相關資料及問題總結

這幾天要把客戶的SPS2003門戶升級到MOSS2007的&#xff0c;客戶SPS2003門戶&#xff0c;數據26G&#xff0c;使用了自定義WebPart、自定義頁面、SSO等功能。升級過程中碰到大量問題。其中主要的問題有幾個&#xff0c;在這里把它們整理一下> 1、sps2003升級時&#xff0c;升…

Milking Time【動態規劃-dp】

Milking Time POJ - 3616 Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that she decides to schedule her next N (1 ≤ N ≤ 1,000,000) hours (conveniently labeled 0..N-1) so that she produces as much milk as po…