這篇文章將為大家詳細(xì)講解有關(guān)static關(guān)鍵字作用是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
創(chuàng)新互聯(lián)憑借在網(wǎng)站建設(shè)、網(wǎng)站推廣領(lǐng)域領(lǐng)先的技術(shù)能力和多年的行業(yè)經(jīng)驗(yàn),為客戶提供超值的營(yíng)銷(xiāo)型網(wǎng)站建設(shè)服務(wù),我們始終認(rèn)為:好的營(yíng)銷(xiāo)型網(wǎng)站就是好的業(yè)務(wù)員。我們已成功為企業(yè)單位、個(gè)人等客戶提供了成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)服務(wù),以良好的商業(yè)信譽(yù),完善的服務(wù)及深厚的技術(shù)力量處于同行領(lǐng)先地位。
static關(guān)鍵字的含義及使用場(chǎng)景
static是Java50個(gè)關(guān)鍵字之一。static關(guān)鍵字可以用來(lái)修飾代碼塊表示靜態(tài)代碼塊,修飾成員變量表示全局靜態(tài)成員變量,修飾方法表示靜態(tài)方法。(注意:不能修飾普通類(lèi),除了內(nèi)部類(lèi),這是為什么?)
class A { static { System.out.println("A : 靜態(tài)代碼塊"); } static int i ; // 靜態(tài)變量 static void method() { System.out.println("A: 靜態(tài)方法"); } }
簡(jiǎn)而言之,被static關(guān)鍵字修飾的內(nèi)容都是靜態(tài)的。
靜態(tài)是相對(duì)于動(dòng)態(tài)的,動(dòng)態(tài)是指Java程序在JVM上運(yùn)行時(shí),JVM會(huì)根據(jù)程序的需要?jiǎng)討B(tài)創(chuàng)建對(duì)象并存儲(chǔ)對(duì)象(分配內(nèi)存),對(duì)象使命結(jié)束后,對(duì)象會(huì)被垃圾回收器銷(xiāo)毀,即內(nèi)存回收由JVM統(tǒng)一管理并分配給其他新創(chuàng)建的對(duì)象;靜態(tài)是指Java程序還沒(méi)有運(yùn)行時(shí),JVM就會(huì)為加載的類(lèi)分配空間存儲(chǔ)被static關(guān)鍵字修飾的內(nèi)容;如靜態(tài)成員變量,Java類(lèi)加載到JVM中,JVM會(huì)把類(lèi)以及類(lèi)的靜態(tài)成員變量存儲(chǔ)在方法區(qū),我們知道方法區(qū)是線程共享且很少發(fā)生GC的區(qū)域,所以被static關(guān)鍵字修飾的內(nèi)容都是全局共享的,且只會(huì)為其分配一次存儲(chǔ)空間。
所以當(dāng)類(lèi)的某些內(nèi)容不屬于對(duì)象,而由對(duì)象共享即屬于類(lèi)的時(shí)候,就可以考慮是否用static關(guān)鍵字進(jìn)行修飾。
static關(guān)鍵字的的作用
1 修飾代碼塊
類(lèi)中用static關(guān)鍵字修飾的代碼塊稱為靜態(tài)代碼,反之沒(méi)有用static關(guān)鍵字修飾的代碼塊稱為實(shí)例代碼塊。
實(shí)例代碼塊會(huì)隨著對(duì)象的創(chuàng)建而執(zhí)行,即每個(gè)對(duì)象都會(huì)有自己的實(shí)例代碼塊,表現(xiàn)出來(lái)就是實(shí)例代碼塊的運(yùn)行結(jié)果會(huì)影響當(dāng)前對(duì)象的內(nèi)容,并隨著對(duì)象的銷(xiāo)毀而消失(內(nèi)存回收);而靜態(tài)代碼塊是當(dāng)Java類(lèi)加載到JVM內(nèi)存中而執(zhí)行的代碼塊,由于類(lèi)的加載在JVM運(yùn)行期間只會(huì)發(fā)生一次,所以靜態(tài)代碼塊也只會(huì)執(zhí)行一次。
因?yàn)殪o態(tài)代碼塊的主要作用是用來(lái)進(jìn)行一些復(fù)雜的初始化工作,所以靜態(tài)代碼塊跟隨類(lèi)存儲(chǔ)在方法區(qū)的表現(xiàn)形式是靜態(tài)代碼塊執(zhí)行的結(jié)果存儲(chǔ)在方法區(qū),即初始化量存儲(chǔ)在方法區(qū)并被線程共享。
2 修飾成員變量
類(lèi)中用static關(guān)鍵字修飾的成員變量稱為靜態(tài)成員變量,因?yàn)閟tatic不能修飾局部變量(為什么?),因此靜態(tài)成員變量也能稱為靜態(tài)變量。靜態(tài)變量跟代碼塊類(lèi)似,在類(lèi)加載到JVM內(nèi)存中,JVM會(huì)把靜態(tài)變量放入方法區(qū)并分配內(nèi)存,也由線程共享。訪問(wèn)形式是:類(lèi)名.靜態(tài)成員名。
public class StaticTest { public static void main(String[] args) { System.out.println(D.i); System.out.println(new D().i); } } class D { static { i = 2; System.out.println("D : 靜態(tài)代碼塊1"); } static int i; }
靜態(tài)變量存儲(chǔ)在類(lèi)的信息中,且可以在線程間共享,那么它當(dāng)然也屬于該類(lèi)的每個(gè)對(duì)象,因此可以通過(guò)對(duì)象訪問(wèn)靜態(tài)變量,但編譯器并不支持這么做,且會(huì)給出警告。
注意:
一個(gè)類(lèi)的靜態(tài)變量和該類(lèi)的靜態(tài)代碼塊的加載順序。類(lèi)會(huì)優(yōu)先加載靜態(tài)變量,然后加載靜態(tài)代碼塊,但有多個(gè)靜態(tài)變量和多個(gè)代碼塊時(shí),會(huì)按照編寫(xiě)的順序進(jìn)行加載。
class D { static { i = 2; System.out.println("D : 靜態(tài)代碼塊1"); } static { i = 6; System.out.println("D : 靜態(tài)代碼塊2"); } static int i; }
可以想一下運(yùn)行的結(jié)果。
靜態(tài)變量可以不用顯式的初始化,JVM會(huì)默認(rèn)給其相應(yīng)的默認(rèn)值。如基本數(shù)據(jù)類(lèi)型的byte為0,short為0,char為\u0000,int為0,long為0L,float為0.0f,double為0.0d,boolean為false,引用類(lèi)型統(tǒng)一為null。
靜態(tài)變量既然是JVM內(nèi)存中共享的且可以改變,那么對(duì)它的訪問(wèn)會(huì)引起線程安全問(wèn)題(線程A改寫(xiě)的同時(shí),線程B獲取它的值,那么獲取的是修改前的值還是修改后的值呢?),所以使用靜態(tài)變量的同時(shí)要考慮多線程情況。如果能確保靜態(tài)變量不可變,那么可以用final關(guān)鍵字一起使用避免線程安全問(wèn)題;否則需要采用同步的方式避免線程安全問(wèn)題,如與volatile關(guān)鍵字一起使用等。
static關(guān)鍵不能修飾局部變量,包括實(shí)例方法和靜態(tài)方法,不然就會(huì)與static關(guān)鍵字的初衷-共享相違背。
3 修飾方法
用static關(guān)鍵字修飾的方法稱為靜態(tài)方法,否則稱為實(shí)例方法。通過(guò)類(lèi)名.方法名調(diào)用,但需要注意靜態(tài)方法可以直接調(diào)用類(lèi)的靜態(tài)變量和其他靜態(tài)方法,不能直接調(diào)用成員變量和實(shí)例方法(除非通過(guò)對(duì)象調(diào)用)。
class D { static { i = 2; System.out.println("D : 靜態(tài)代碼塊"); } static final int i; int j; static void method() { System.out.println(i); System.out.println(new D().j); method1(); new D().method2(); } static void method1() { System.out.println(i); } void method2() { System.out.println(i); } }
注意:既然類(lèi)的實(shí)例方法需要對(duì)象調(diào)用才能訪問(wèn),而靜態(tài)方法直接通過(guò)類(lèi)名就能訪問(wèn),那么在不考慮部署服務(wù)器的情況下,一個(gè)類(lèi)是如何開(kāi)始執(zhí)行的呢?最大的可能就是通過(guò)“類(lèi)名.靜態(tài)方法”啟動(dòng)Java,而我定義那么多靜態(tài)方法,JVM又是如何知道主入口呢?
或許,你想到了main方法。
沒(méi)錯(cuò),就是main方法被Java規(guī)范定義成Java類(lèi)的主入口。Java類(lèi)的運(yùn)行都由main方法開(kāi)啟:
public static void main(String[] args) { for (String arg : args) { // 參數(shù)由外部定義 System.out.println(arg); }}
但注意main并不是Java關(guān)鍵字,它只是一個(gè)規(guī)定的程序入口的方法名字;另外main方法可以重載。
注意:static關(guān)鍵字雖然不能修飾普通類(lèi),但可以用static關(guān)鍵字修飾內(nèi)部類(lèi)使其變成靜態(tài)內(nèi)部類(lèi)。static關(guān)鍵字本身的含義就是共享,而Java類(lèi)加載到JVM內(nèi)存的方法區(qū),也是線程共享的,所以沒(méi)必要用static關(guān)鍵字修飾普通類(lèi)。
4 靜態(tài)導(dǎo)入
在用import導(dǎo)入包或者類(lèi)時(shí),可以用static修飾包名或者類(lèi),表示靜態(tài)導(dǎo)入。靜態(tài)導(dǎo)入可以與動(dòng)態(tài)導(dǎo)入放在一起比較來(lái)加深理解。
動(dòng)態(tài)導(dǎo)入是當(dāng)你程序運(yùn)行時(shí)需要new一個(gè)不在此包中的類(lèi)的對(duì)象時(shí),才會(huì)根據(jù)全路徑類(lèi)名加載類(lèi);而靜態(tài)導(dǎo)入則是隨著類(lèi)的加載而加載靜態(tài)導(dǎo)入的類(lèi),所以它是提前導(dǎo)入的。
public class StaticTest { static void method1() { System.out.println("static method1"); } static void method2() { System.out.println("static method2"); } }
靜態(tài)導(dǎo)入:
import static com.starry.staticImport.StaticTest.method1; public class Client { public static void main(String[] args) { method1(); // StaticTest.method2(); } }
注意method1()是靜態(tài)導(dǎo)入,所以可以不需要通過(guò)類(lèi)名訪問(wèn);而method2()沒(méi)有導(dǎo)入,則需要通過(guò)類(lèi)名調(diào)用。那么什么時(shí)候需要靜態(tài)導(dǎo)入呢?
靜態(tài)導(dǎo)入常用于靜態(tài)方法以及含有靜態(tài)方法的類(lèi),枚舉類(lèi)等的導(dǎo)入,可以在編譯階段確定導(dǎo)入類(lèi)的信息或者方法信息。
static關(guān)鍵字的缺點(diǎn)
封裝是Java類(lèi)的三大特性之一,也是面向?qū)ο蟮闹饕匦?。因?yàn)椴恍枰ㄟ^(guò)對(duì)象,而直接通過(guò)類(lèi)就能訪問(wèn)類(lèi)的屬性和方法,這有點(diǎn)破壞類(lèi)的封裝性;所以除了Utils類(lèi),代碼中應(yīng)該盡量少用static關(guān)鍵字修飾變量和方法
關(guān)于static關(guān)鍵字作用是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
當(dāng)前題目:static關(guān)鍵字作用是什么
標(biāo)題鏈接:http://m.rwnh.cn/article14/jepdge.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、網(wǎng)站設(shè)計(jì)、網(wǎng)站導(dǎo)航、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站內(nèi)鏈、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)