java中的static關鍵字說清楚還得靠JVM
持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第2天,點選檢視活動詳情
前言
- Java中Static想必大家一定使用過吧。他是用來修飾類或者成員變數或者方法的。
- 關於Static的用法還是很簡單的,因為他就是一個修飾詞。但是如果不理解他修飾的作用原理的話,可能會鬧出bug來
變數
- 上圖是一個簡化的JVM記憶體結構模型。學習過JVM的都知道我們建立的物件正常情況下都是在堆中的。那麼我們訪問物件中的屬性自然也就存放在堆中的。
- 但是當static修飾屬性之後他就發生了變化了。
class Demo {
//成員變數
public int num = 100;
//靜態成員變數
public static int count = 200;
//靜態方法
public static void method(){
System.out.println(count);
}
}
- num屬性屬於常規屬性,count屬性屬於靜態變數。他們不僅僅是名稱上的不同。從JVM的角度看他的存放位置也不同。
- 首先num依賴於具體的物件,所以他和物件存放在一起都是堆中。
- 而count獨立於物件。JVM中專門有一塊空間用於存放靜態變數。這個空間我們叫做方法區。
方法
- 除了修飾變數外,static還可以修飾方法。被修飾的方法我們叫做靜態方法 。靜態方法的特點和靜態變數一樣都屬於類而不是物件。靜態方法內部只能訪問靜態變數而無法通過this物件進行訪問物件屬性。
- 總結下來就是靜態方法內部只能訪問靜態變數無法訪問非靜態變數。
- 除了靜態方法外,還有一個特殊的方法叫做靜態程式碼塊。這個方法不需要我們準備方法名,入參,出參等等。只需要準備方法體。關於方法體內部和靜態方法內部要求是一樣的。
- 關於靜態程式碼塊和靜態方法他們和普通方法還有一個重要的區別就是執行時機。靜態變數與普通變數的區別就是記憶體分佈位置,而方法是在棧中操作的,不涉及記憶體的儲存,所以區別就是方法執行的時機。這裡需要我們提前瞭解點類載入機制。
- 首先我們一個類的載入分為五個過程。首先是載入class元資訊,最後一步是進行初始化。至於前面三步我們這裡可以不理解。重點知道在類載入的最後階段會進行初始化,而初始化的操作就是執行靜態方法和靜態程式碼塊。
- 從類載入過程中我們也能夠看的出來靜態方法是不依賴於物件的呼叫的。因為靜態方法中只能使用到靜態屬性。也就是說靜態屬性使用時還沒有建立物件。這也佐證了靜態變數不依賴物件的說法。
總結
- 本文主要講解Java基礎,請原諒我沒有華麗的詞藻渲染出色的文章。雖然基礎但往往是我們容易忽略的知識點。
- 只有不斷的學習,才能不斷的進步,關於static的進一步使用場景,目前我能想到的就是單例模式中會使用。
「其他文章」
- 避免回表,引入索引下推|提高索引命中率 | 提前下班啦
- TDengine 時序性資料庫為什麼海量資料下不卡頓呢
- 神奇的XPath,快速完成前端及XML的元素定位,茫茫大海不迷路
- springboot通用分支處理---還在硬編碼特殊處理邏輯?超級管理員不應該被區別對待
- Spring事務太強大了,相容資料庫同時給我們提供多種組合應對業務需求
- java物件在記憶體中如何分佈 | java上鎖原來就是記憶體佔位,so easy
- linux三劍客之編輯器sed出廠
- linux三劍客awk教你如何裁剪結果集
- 執行緒池7個引數拿捏死死的,完爆面試官
- 執行緒池存在的意義
- 多年程式設計師總結下來的懶人必備指令碼之進度條⚠️製作
- java中的static關鍵字說清楚還得靠JVM
- 設計模式存在哪些關聯關係,六種關係傻傻分不清--- UML圖示詳解
- 每次需求評審產品總是讓我提高程式碼複用,說白了就是合成複用原則
- 越級上報不可行,各司其職才是王道---迪米特法則
- 偏向鎖/輕量鎖/重級鎖鎖鎖更健康,上鎖解鎖到底是怎麼完成實現的,我來告訴你
- 狸貓換太子里氏替換原則;不要一味的進行抽象否則最後你無法hold你的物件
- 設計模式是我擺脫碼畜的唯一出路---依賴倒轉原則
- 學好數理化,寫遍所有程式碼都不怕,我用數學分類討論的思想解決
- synchronized已經不在臃腫了,放下對他的成見之初識輕量級鎖