Java中static關(guān)鍵字的作用解析
一、全局變量、局部變量
全局變量就好比一個容器或者一個公用的東西一樣,就類似外面公共場所的凳子一樣,大家都可以使用這個凳子。Java 中,不能在所有類之外定義全局變量,只能通過在一個類中定義公用、靜態(tài)的變量來實(shí)現(xiàn)一個全局變量。
局部變量就是局部的東西,如果全局變量是桌子,局部變量就類似于抽屜,只能在一小部分地方使用,很局限。全局變量是外面公共場所的凳子,局部變量則就像某個酒店的凳子一樣,在酒店內(nèi)部,只有去住酒店才能使用。
二、static 是什么
Java 中并不存在全局變量的概念,但是可以通過 static 來實(shí)現(xiàn)一個“偽全局”的概念,Java 中 static 表示“全局”或者“靜態(tài)”的意思,用來修飾成員變量和成員方法,當(dāng)然也可以修飾代碼塊。 Java 把內(nèi)存分為棧內(nèi)存和堆內(nèi)存,其中棧內(nèi)存用來存放一些基本類型的變量、數(shù)組和對象的引用,堆內(nèi)存主要存放一些對象。
在 JVM 加載一個類的時候,若該類存在 static 修飾的成員變量和成員方法,則會為這些成員變量和成員方法在固定的位置開辟一個固定大小的內(nèi)存區(qū)域,有了這些“固定”的特性,那么 JVM 就可以非常方便地訪問它們。同時如果靜態(tài)的成員變量和成員方法不出作用域的話,它們的句柄都會保持不變。同時 static 所蘊(yùn)含“靜態(tài)”的概念表示著它是不可恢復(fù)的,即在那個地方,你修改了,它是不會變回原樣的;你清理了,它就不會回來了。 同時被 static 修飾的成員變量和成員方法是獨(dú)立于該類的,它不依賴于某個特定的實(shí)例變量,也就是說它被該類的所有實(shí)例共享。所有實(shí)例的引用都指向同一個地方,任何一個實(shí)例對其的修改都會導(dǎo)致其它實(shí)例的變化。
三、static 的特點(diǎn)和弊端
特點(diǎn)
- 隨著類的加載而加載。
- 優(yōu)先于對象存在。
- 所有對象共享。
- 可以被類名直接調(diào)用。
弊端
- 生命周期過長,隨著類的消失而消失。
- 靜態(tài)方法只能訪問靜態(tài)成員。
- 靜態(tài)方法中不能使用 this,super 關(guān)鍵字。
- static 變量在定義時必須要進(jìn)行初始化,且初始化時間要早于非靜態(tài)變量。
總結(jié):無論是變量,方法,還是代碼塊,只要用 static 修飾,就是在類被加載時就已經(jīng)”準(zhǔn)備好了”,也就是可以被使用或者已經(jīng)被執(zhí)行,都可以脫離對象而執(zhí)行。反之,如果沒有 static,則必須要依賴于對象實(shí)例。
四、怎么使用 static
static 變量
static 修飾的變量,稱之為靜態(tài)變量,沒有用 static 修飾的變量稱之為實(shí)例變量。二者的區(qū)別是: 靜態(tài)變量是隨著類加載時被完成初始化的,它在內(nèi)存中僅有一個,且 JVM 也只會為它分配一次內(nèi)存,同時類所有的實(shí)例都共享靜態(tài)變量,可以直接通過類名來訪問它。而實(shí)例變量則不同,它是伴隨著實(shí)例的,每創(chuàng)建一個實(shí)例就會產(chǎn)生一個實(shí)例變量,它與該實(shí)例同生共死。 所以一般在【對象之間共享數(shù)據(jù)】時使用靜態(tài)變量,訪問方便。
static 方法
static 修飾的方法,稱之為靜態(tài)方法,通過類名對其進(jìn)行直接調(diào)用。由于它在類加載的時候就存在了,它不依賴于任何實(shí)例,所以 static 方法必須實(shí)現(xiàn),也就是說它不能是抽象方法 abstract。 static 方法是類中的一種特殊方法,只有在真正需要它們的時候才會將方法聲明為 static。如 Math 類的所有方法都是靜態(tài) static 的。
static 代碼塊
被 static 修飾的代碼塊,稱之為靜態(tài)代碼塊。靜態(tài)代碼塊會隨著類的加載一塊執(zhí)行,而且它可以隨意放,可以存在于該類的任何地方。
五、Java 中為什么靜態(tài)方法可以直接被調(diào)用
把類看作是一個房子。房子里面所有的人共用一套家具。也就是說,這些家具是唯一的,如果某個家具壞了,那么大家都用不了。
再看定義,Java 的靜態(tài)變量也叫做類變量,它開始于類的創(chuàng)建,結(jié)束于類的消亡。非靜態(tài)變量叫做實(shí)例變量,它開始于類的實(shí)例的創(chuàng)建,結(jié)束于類的實(shí)例的消亡。
靜態(tài)變量被所有實(shí)例所共享。如上面的例子,座椅板凳是類變量,它們是在房子被建好了之后就被添加放置進(jìn)來,而且基本都是唯一的。
人就相當(dāng)于實(shí)例,每個人都能用這些家具,但是如果家具一旦損壞,那就是壞了,或者把某一個家具搬走,那么所有的人都用不了這個家具,房子里也不存在這個家具了。
房子里可以進(jìn)很多人,可以進(jìn)張三,可以進(jìn)李四。所以這些人就是類的實(shí)例對象,他們身上穿的衣服就可以叫做實(shí)例變量。
如果一個類中有靜態(tài)變量的話,程序首先會把該靜態(tài)變量加載進(jìn)內(nèi)存中,也就是在堆中開辟一個區(qū)域?qū)iT存放。以后不管 new 多少個類的對象,該靜態(tài)變量永遠(yuǎn)都是在那里的。也就是說,靜態(tài)變量在類的初始化一次后,系統(tǒng)就不會為該變量開辟新的內(nèi)存空間。而每 new 一個類的對象,系統(tǒng)就會重新在堆內(nèi)存中開辟一個新空間來存放該類的實(shí)例對象,并且棧中也會有一個新的引用變量去指向它。
靜態(tài)方法也是類似,但是有一點(diǎn)要強(qiáng)調(diào),靜態(tài)方法中不能調(diào)用非靜態(tài)方法。因?yàn)楸?static 修飾的方法會首先被 Classloader 對象先加載進(jìn)內(nèi)存,而這個時候可能其它的非靜態(tài)方法或者變量還沒有被加載進(jìn)來。就好比現(xiàn)在想做包子,現(xiàn)在面粉被 static 修飾,首先已經(jīng)拿到身邊,可是因?yàn)榘羽W不是 static 修飾的,所以可能包子餡兒還沒運(yùn)過來,你說怎么做的出包子呢。被 static 修飾過的都是隨著類的初始化后就產(chǎn)生了,在堆內(nèi)存中都有一塊專門的區(qū)域來存放,所以只需要類名點(diǎn)方法名或者變量名即可。而非靜態(tài)的就必須通過類的對象去調(diào)。
六、面試題
誰在前輸出誰
public class StaticDemo { public static void main(String[] args) { System.out.println(StaticDemo.m); } static int m = 80; static { m = 60; } }
無關(guān)順序,永遠(yuǎn)只輸出 80
public class StaticDemo { public static void main(String[] args) { System.out.println(StaticDemo.m); } static int m = 80; static { int m = 60; } }
到此這篇關(guān)于Java中static關(guān)鍵字的作用解析的文章就介紹到這了,更多相關(guān)Java中static關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)數(shù)字金額轉(zhuǎn)化為英文金額功能
在處理財務(wù)數(shù)據(jù)時,有時需要將數(shù)字形式的金額轉(zhuǎn)換成英文描述的形式,比如在生成正式文件或發(fā)票時,本文將介紹如何使用Java實(shí)現(xiàn)這一功能,需要的朋友可以參考下2025-03-03Java中的ThreadPoolExecutor線程池原理細(xì)節(jié)解析
這篇文章主要介紹了Java中的ThreadPoolExecutor線程池原理細(xì)節(jié)解析,ThreadPoolExecutor是一個線程池,最多可使用7個參數(shù)來控制線程池的生成,使用線程池可以避免創(chuàng)建和銷毀線程的資源損耗,提高響應(yīng)速度,并且可以管理線程池中線程的數(shù)量和狀態(tài)等等,需要的朋友可以參考下2023-12-12Springboot+TCP監(jiān)聽服務(wù)器搭建過程圖解
這篇文章主要介紹了Springboot+TCP監(jiān)聽服務(wù)器搭建過程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10springboot中websocket簡單實(shí)現(xiàn)
本文主要介紹了springboot中websocket簡單實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01SpringBoot結(jié)合SpringSecurity實(shí)現(xiàn)圖形驗(yàn)證碼功能
這篇文章主要介紹了SpringBoot + SpringSecurity 實(shí)現(xiàn)圖形驗(yàn)證碼功能,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05Java設(shè)計(jì)模式——工廠設(shè)計(jì)模式詳解
這篇文章主要介紹了Java設(shè)計(jì)模式——工廠設(shè)計(jì)模式詳解,具有一定參考價值,需要的朋友可以了解下。2017-11-11Java語言實(shí)現(xiàn)簡單FTP軟件 FTP上傳下載隊(duì)列窗口實(shí)現(xiàn)(7)
這篇文章主要為大家詳細(xì)介紹了Java語言實(shí)現(xiàn)簡單FTP軟件,F(xiàn)TP上傳下載隊(duì)列窗口的實(shí)現(xiàn)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04