Java中的static關(guān)鍵字解析

Java中的static關(guān)鍵字解析

本文轉(zhuǎn)子博客園埠通,單擊此處閱讀原文

static關(guān)鍵字是很多朋友在編寫代碼和閱讀代碼時(shí)碰到的比較難以理解的一個(gè)關(guān)鍵字豆同,也是各大公司的面試官喜歡在面試時(shí)問到的知識(shí)點(diǎn)之一。下面就先講述一下static關(guān)鍵字的用法和平常容易誤解的地方,最后列舉了一些面試筆試中常見的關(guān)于static的考題。以下是本文的目錄大綱:

一.static關(guān)鍵字的用途

二.static關(guān)鍵字的誤區(qū)

三.常見的筆試面試題

若有不正之處鹅髓,希望諒解并歡迎批評(píng)指正。請(qǐng)尊重作者勞動(dòng)成果京景,轉(zhuǎn)載請(qǐng)標(biāo)明原文鏈接:

http://www.cnblogs.com/dolphin0520/p/3799052.html

一.static關(guān)鍵字的用途

在《Java編程思想》P86頁(yè)有這樣一段話:

“static方法就是沒有this的方法窿冯。在static方法內(nèi)部不能調(diào)用非靜態(tài)方法,反過來(lái)是可以的确徙。而且可以在沒有創(chuàng)建任何對(duì)象的前提下醒串,僅僅通過類本身來(lái)調(diào)用static方法。這實(shí)際上正是static方法的主要用途鄙皇∥叨模”

這段話雖然只是說明了static方法的特殊之處,但是可以看出static關(guān)鍵字的基本作用育苟,簡(jiǎn)而言之较鼓,一句話來(lái)描述就是:

方便在沒有創(chuàng)建對(duì)象的情況下來(lái)進(jìn)行調(diào)用(方法/變量)椎木。

很顯然违柏,被static關(guān)鍵字修飾的方法或者變量不需要依賴于對(duì)象來(lái)進(jìn)行訪問,只要類被加載了香椎,就可以通過類名去進(jìn)行訪問漱竖。

static可以用來(lái)修飾類的成員方法、類的成員變量畜伐,另外可以編寫static代碼塊來(lái)優(yōu)化程序性能馍惹。

1)static方法

static方法一般稱作靜態(tài)方法,由于靜態(tài)方法不依賴于任何對(duì)象就可以進(jìn)行訪問,因此對(duì)于靜態(tài)方法來(lái)說万矾,是沒有this的悼吱,因?yàn)樗灰栏接谌魏螌?duì)象,既然都沒有對(duì)象良狈,就談不上this了后添。并且由于這個(gè)特性,在靜態(tài)方法中不能訪問類的非靜態(tài)成員變量和非靜態(tài)成員方法薪丁,因?yàn)榉庆o態(tài)成員方法/變量都是必須依賴具體的對(duì)象才能夠被調(diào)用遇西。

但是要注意的是,雖然在靜態(tài)方法中不能訪問非靜態(tài)成員方法和非靜態(tài)成員變量严嗜,但是在非靜態(tài)成員方法中是可以訪問靜態(tài)成員方法/變量的粱檀。舉個(gè)簡(jiǎn)單的例子:

在上面的代碼中,由于print2方法是獨(dú)立于對(duì)象存在的漫玄,可以直接用過類名調(diào)用茄蚯。假如說可以在靜態(tài)方法中訪問非靜態(tài)方法/變量的話,那么如果在main方法中有下面一條語(yǔ)句:

MyObject.print2();

此時(shí)對(duì)象都沒有睦优,str2根本就不存在第队,所以就會(huì)產(chǎn)生矛盾了。同樣對(duì)于方法也是一樣刨秆,由于你無(wú)法預(yù)知在print1方法中是否訪問了非靜態(tài)成員變量凳谦,所以也禁止在靜態(tài)成員方法中訪問非靜態(tài)成員方法。

而對(duì)于非靜態(tài)成員方法衡未,它訪問靜態(tài)成員方法/變量顯然是毫無(wú)限制的尸执。

因此,如果說想在不創(chuàng)建對(duì)象的情況下調(diào)用某個(gè)方法缓醋,就可以將這個(gè)方法設(shè)置為static如失。我們最常見的static方法就是main方法,至于為什么main方法必須是static的送粱,現(xiàn)在就很清楚了褪贵。因?yàn)槌绦蛟趫?zhí)行main方法的時(shí)候沒有創(chuàng)建任何對(duì)象,因此只有通過類名來(lái)訪問抗俄。

另外記住脆丁,即使沒有顯示地聲明為static,類的構(gòu)造器實(shí)際上也是靜態(tài)方法动雹。

2)static變量

static變量也稱作靜態(tài)變量槽卫,靜態(tài)變量和非靜態(tài)變量的區(qū)別是:靜態(tài)變量被所有的對(duì)象所共享,在內(nèi)存中只有一個(gè)副本胰蝠,它當(dāng)且僅當(dāng)在類初次加載時(shí)會(huì)被初始化歼培。而非靜態(tài)變量是對(duì)象所擁有的震蒋,在創(chuàng)建對(duì)象的時(shí)候被初始化,存在多個(gè)副本躲庄,各個(gè)對(duì)象擁有的副本互不影響查剖。

static成員變量的初始化順序按照定義的順序進(jìn)行初始化。

3)static代碼塊

static關(guān)鍵字還有一個(gè)比較關(guān)鍵的作用就是 用來(lái)形成靜態(tài)代碼塊以優(yōu)化程序性能噪窘。static塊可以置于類中的任何地方梗搅,類中可以有多個(gè)static塊。在類初次被加載的時(shí)候效览,會(huì)按照static塊的順序來(lái)執(zhí)行每個(gè)static塊无切,并且只會(huì)執(zhí)行一次。

為什么說static塊可以用來(lái)優(yōu)化程序性能丐枉,是因?yàn)樗奶匦?只會(huì)在類加載的時(shí)候執(zhí)行一次哆键。下面看個(gè)例子:

1

2

3

4

5

6

7

8

9

10

11

12

13classPerson{

privateDate birthDate;

publicPerson(Date birthDate) {

this.birthDate = birthDate;

}

booleanisBornBoomer() {

Date startDate = Date.valueOf("1946");

Date endDate = Date.valueOf("1964");

returnbirthDate.compareTo(startDate)>=0&& birthDate.compareTo(endDate) <0;

}

}

isBornBoomer是用來(lái)這個(gè)人是否是1946-1964年出生的,而每次isBornBoomer被調(diào)用的時(shí)候瘦锹,都會(huì)生成startDate和birthDate兩個(gè)對(duì)象籍嘹,造成了空間浪費(fèi),如果改成這樣效率會(huì)更好:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16classPerson{

privateDate birthDate;

privatestaticDate startDate,endDate;

static{

startDate = Date.valueOf("1946");

endDate = Date.valueOf("1964");

}

publicPerson(Date birthDate) {

this.birthDate = birthDate;

}

booleanisBornBoomer() {

returnbirthDate.compareTo(startDate)>=0&& birthDate.compareTo(endDate) <0;

}

}

因此弯院,很多時(shí)候會(huì)將一些只需要進(jìn)行一次的初始化操作都放在static代碼塊中進(jìn)行辱士。

二.static關(guān)鍵字的誤區(qū)

1.static關(guān)鍵字會(huì)改變類中成員的訪問權(quán)限嗎?

有些初學(xué)的朋友會(huì)將java中的static與C/C++中的static關(guān)鍵字的功能混淆了听绳。在這里只需要記住一點(diǎn):與C/C++中的static不同颂碘,Java中的static關(guān)鍵字不會(huì)影響到變量或者方法的作用域。在Java中能夠影響到訪問權(quán)限的只有private椅挣、public头岔、protected(包括包訪問權(quán)限)這幾個(gè)關(guān)鍵字∈笾ぃ看下面的例子就明白了:

提示錯(cuò)誤"Person.age 不可視"峡竣,這說明static關(guān)鍵字并不會(huì)改變變量和方法的訪問權(quán)限。

2.能通過this訪問靜態(tài)成員變量嗎量九?

雖然對(duì)于靜態(tài)方法來(lái)說沒有this适掰,那么在非靜態(tài)方法中能夠通過this訪問靜態(tài)成員變量嗎?先看下面的一個(gè)例子荠列,這段代碼輸出的結(jié)果是什么类浪?

1

2

3

4

5

6

7

8

9

10

11

12publicclassMain {

staticintvalue =33;

publicstaticvoidmain(String[] args)throwsException{

newMain().printValue();

}

privatevoidprintValue(){

intvalue =3;

System.out.println(this.value);

}

}

View Code

這里面主要考察隊(duì)this和static的理解。this代表什么弯予?this代表當(dāng)前對(duì)象戚宦,那么通過new Main()來(lái)調(diào)用printValue的話个曙,當(dāng)前對(duì)象就是通過new Main()生成的對(duì)象锈嫩。而static變量是被對(duì)象所享有的受楼,因此在printValue中的this.value的值毫無(wú)疑問是33。在printValue方法內(nèi)部的value是局部變量呼寸,根本不可能與this關(guān)聯(lián)艳汽,所以輸出結(jié)果是33。在這里永遠(yuǎn)要記住一點(diǎn):靜態(tài)成員變量雖然獨(dú)立于對(duì)象对雪,但是不代表不可以通過對(duì)象去訪問河狐,所有的靜態(tài)方法和靜態(tài)變量都可以通過對(duì)象訪問(只要訪問權(quán)限足夠)。

3.static能作用于局部變量么瑟捣?

在C/C++中static是可以作用域局部變量的馋艺,但是在Java中切記:static是不允許用來(lái)修飾局部變量。不要問為什么迈套,這是Java語(yǔ)法的規(guī)定捐祠。

三.常見的筆試面試題

下面列舉一些面試筆試中經(jīng)常遇到的關(guān)于static關(guān)鍵字的題目,僅供參考桑李,如有補(bǔ)充歡迎下方留言踱蛀。

1.下面這段代碼的輸出結(jié)果是什么?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25publicclassTestextendsBase{

static{

System.out.println("test static");

}

publicTest(){

System.out.println("test constructor");

}

publicstaticvoidmain(String[] args) {

newTest();

}

}

classBase{

static{

System.out.println("base static");

}

publicBase(){

System.out.println("base constructor");

}

}

View Code

至于為什么是這個(gè)結(jié)果贵白,我們先不討論率拒,先來(lái)想一下這段代碼具體的執(zhí)行過程,在執(zhí)行開始禁荒,先要尋找到main方法猬膨,因?yàn)閙ain方法是程序的入口,但是在執(zhí)行main方法之前呛伴,必須先加載Test類寥掐,而在加載Test類的時(shí)候發(fā)現(xiàn)Test類繼承自Base類,因此會(huì)轉(zhuǎn)去先加載Base類磷蜀,在加載Base類的時(shí)候召耘,發(fā)現(xiàn)有static塊,便執(zhí)行了static塊褐隆。在Base類加載完成之后污它,便繼續(xù)加載Test類,然后發(fā)現(xiàn)Test類中也有static塊庶弃,便執(zhí)行static塊衫贬。在加載完所需的類之后,便開始執(zhí)行main方法歇攻。在main方法中執(zhí)行new Test()的時(shí)候會(huì)先調(diào)用父類的構(gòu)造器固惯,然后再調(diào)用自身的構(gòu)造器。因此缴守,便出現(xiàn)了上面的輸出結(jié)果葬毫。

2.這段代碼的輸出結(jié)果是什么镇辉?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35publicclassTest {

Person person =newPerson("Test");

static{

System.out.println("test static");

}

publicTest() {

System.out.println("test constructor");

}

publicstaticvoidmain(String[] args) {

newMyClass();

}

}

classPerson{

static{

System.out.println("person static");

}

publicPerson(String str) {

System.out.println("person "+str);

}

}

classMyClassextendsTest {

Person person =newPerson("MyClass");

static{

System.out.println("myclass static");

}

publicMyClass() {

System.out.println("myclass constructor");

}

}

View Code

類似地,我們還是來(lái)想一下這段代碼的具體執(zhí)行過程贴捡。首先加載Test類忽肛,因此會(huì)執(zhí)行Test類中的static塊。接著執(zhí)行new MyClass()烂斋,而MyClass類還沒有被加載屹逛,因此需要加載MyClass類。在加載MyClass類的時(shí)候汛骂,發(fā)現(xiàn)MyClass類繼承自Test類罕模,但是由于Test類已經(jīng)被加載了,所以只需要加載MyClass類帘瞭,那么就會(huì)執(zhí)行MyClass類的中的static塊手销。在加載完之后,就通過構(gòu)造器來(lái)生成對(duì)象图张。而在生成對(duì)象的時(shí)候锋拖,必須先初始化父類的成員變量,因此會(huì)執(zhí)行Test中的Person person = new Person()祸轮,而Person類還沒有被加載過兽埃,因此會(huì)先加載Person類并執(zhí)行Person類中的static塊,接著執(zhí)行父類的構(gòu)造器适袜,完成了父類的初始化柄错,然后就來(lái)初始化自身了,因此會(huì)接著執(zhí)行MyClass中的Person person = new Person()苦酱,最后執(zhí)行MyClass的構(gòu)造器售貌。

3.這段代碼的輸出結(jié)果是什么?

1

2

3

4

5

6

7

8

9

10

11

12

13publicclassTest {

static{

System.out.println("test static 1");

}

publicstaticvoidmain(String[] args) {

}

static{

System.out.println("test static 2");

}

}

View Code

雖然在main方法中沒有任何語(yǔ)句疫萤,但是還是會(huì)輸出颂跨,原因上面已經(jīng)講述過了。另外扯饶,static塊可以出現(xiàn)類中的任何地方(只要不是方法內(nèi)部恒削,記住,任何方法內(nèi)部都不行)尾序,并且執(zhí)行是按照static塊的順序執(zhí)行的钓丰。

參考資料:

http://lavasoft.blog.51cto.com/62575/18771/

http://www.51cto.com/specbook/24/35011.htm

http://blog.csdn.net/zhu_apollo/article/details/1888219

http://blog.sina.com.cn/s/blog_70b845780100n9zz.html

http://hi.baidu.com/yuiezt/item/b71ff5fbfe9c385cc8f3370d

http://bbs.csdn.net/topics/330251070

http://yezixingchen.iteye.com/blog/1597186

《Java編程思想》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市每币,隨后出現(xiàn)的幾起案子携丁,更是在濱河造成了極大的恐慌,老刑警劉巖兰怠,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梦鉴,死亡現(xiàn)場(chǎng)離奇詭異李茫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)尚揣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門涌矢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)掖举,“玉大人快骗,你說我怎么就攤上這事∷危” “怎么了方篮?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)励负。 經(jīng)常有香客問我藕溅,道長(zhǎng),這世上最難降的妖魔是什么继榆? 我笑而不...
    開封第一講書人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任巾表,我火速辦了婚禮,結(jié)果婚禮上略吨,老公的妹妹穿的比我還像新娘集币。我一直安慰自己,他們只是感情好翠忠,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開白布鞠苟。 她就那樣靜靜地躺著,像睡著了一般秽之。 火紅的嫁衣襯著肌膚如雪当娱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評(píng)論 1 290
  • 那天考榨,我揣著相機(jī)與錄音跨细,去河邊找鬼。 笑死河质,一個(gè)胖子當(dāng)著我的面吹牛扼鞋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播愤诱,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼云头,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了淫半?” 一聲冷哼從身側(cè)響起溃槐,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎科吭,沒想到半個(gè)月后昏滴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猴鲫,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年谣殊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拂共。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡姻几,死狀恐怖宜狐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蛇捌,我是刑警寧澤抚恒,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站络拌,受9級(jí)特大地震影響俭驮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜春贸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一混萝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧萍恕,春花似錦逸嘀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至维哈,卻和暖如春绳姨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阔挠。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工飘庄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人购撼。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓跪削,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親迂求。 傳聞我的和親對(duì)象是個(gè)殘疾皇子碾盐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 作者:海子原文地址:http://www.cnblogs.com/dolphin0520/ static關(guān)鍵字是很...
    IT程序獅閱讀 1,218評(píng)論 0 16
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法宪萄,類相關(guān)的語(yǔ)法代兵,內(nèi)部類的語(yǔ)法珍特,繼承相關(guān)的語(yǔ)法差油,異常的語(yǔ)法抹估,線程的語(yǔ)...
    子非魚_t_閱讀 31,598評(píng)論 18 399
  • 文章大綱:1.為什么static會(huì)有這樣的效果奶陈?2.static的使用3.static誤區(qū)4.static面試題 ...
    檸檬烏冬面閱讀 5,847評(píng)論 3 43
  • 猶愛慢節(jié)奏的電影滞时,例如《面包和湯和貓咪好天氣》主角亞紀(jì)子原本是一位與媽媽一起生活的單身編輯狗热。由于媽媽突然去世,公司...
    中三二閱讀 201評(píng)論 0 1
  • 張勛復(fù)辟,有種說法是掂榔,在張勛的提議下继效,參加會(huì)議的各方代表在一件黃緞子上簽名,以是同意宣統(tǒng)皇帝復(fù)位衅疙。 傳說張勛復(fù)辟失...
    c0ee46805838閱讀 314評(píng)論 0 0