瘋狂Java之學習筆記(29)-----------static

      網友投稿 674 2025-04-01

      瘋狂Java之學習筆記(29)-----------static


      Java中的static關鍵字解析

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

      一.static關鍵字的用途

      二.static關鍵字的誤區

      三.常見的筆試面試題

      本文轉自http://www.cnblogs.com/dolphin0520/p/3799052.html

      一.static關鍵字的用途

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

      “static方法就是沒有this的方法。在static方法內部不能調用非靜態方法,反過來是可以的。而且可以在沒有創建任何對象的前提下,僅僅通過類本身來調用static方法。這實際上正是static方法的主要用途。”

      這段話雖然只是說明了static方法的特殊之處,但是可以看出static關鍵字的基本作用,簡而言之,一句話來描述就是:

      方便在沒有創建對象的情況下來進行調用(方法/變量)。

      很顯然,被static關鍵字修飾的方法或者變量不需要依賴于對象來進行訪問,只要類被加載了,就可以通過類名去進行訪問。

      static可以用來修飾類的成員方法、類的成員變量,另外可以編寫static代碼塊來優化程序性能。

      1)static方法

      static方法一般稱作靜態方法,由于靜態方法不依賴于任何對象就可以進行訪問,因此對于靜態方法來說,是沒有this的,因為它不依附于任何對象,既然都沒有對象,就談不上this了。并且由于這個特性,在靜態方法中不能訪問類的非靜態成員變量和非靜態成員方法,因為非靜態成員方法/變量都是必須依賴具體的對象才能夠被調用。

      但是要注意的是,雖然在靜態方法中不能訪問非靜態成員方法和非靜態成員變量,但是在非靜態成員方法中是可以訪問靜態成員方法/變量的。舉個簡單的例子:

      在上面的代碼中,由于print2方法是獨立于對象存在的,可以直接用過類名調用。假如說可以在靜態方法中訪問非靜態方法/變量的話,那么如果在main方法中有下面一條語句:

      MyObject.print2();

      此時對象都沒有,str2根本就不存在,所以就會產生矛盾了。同樣對于方法也是一樣,由于你無法預知在print1方法中是否訪問了非靜態成員變量,所以也禁止在靜態成員方法中訪問非靜態成員方法。

      而對于非靜態成員方法,它訪問靜態成員方法/變量顯然是毫無限制的。

      因此,如果說想在不創建對象的情況下調用某個方法,就可以將這個方法設置為static。我們最常見的static方法就是main方法,至于為什么main方法必須是static的,現在就很清楚了。因為程序在執行main方法的時候沒有創建任何對象,因此只有通過類名來訪問。

      另外記住,即使沒有顯示地聲明為static,類的構造器實際上也是靜態方法。

      2)static變量

      static變量也稱作靜態變量,靜態變量和非靜態變量的區別是:靜態變量被所有的對象所共享,在內存中只有一個副本,它當且僅當在類初次加載時會被初始化。而非靜態變量是對象所擁有的,在創建對象的時候被初始化,存在多個副本,各個對象擁有的副本互不影響。

      static成員變量的初始化順序按照定義的順序進行初始化。

      3)static代碼塊

      static關鍵字還有一個比較關鍵的作用就是 用來形成靜態代碼塊以優化程序性能。static塊可以置于類中的任何地方,類中可以有多個static塊。在類初次被加載的時候,會按照static塊的順序來執行每個static塊,并且只會執行一次。

      為什么說static塊可以用來優化程序性能,是因為它的特性:只會在類加載的時候執行一次。下面看個例子:

      ?

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      class? Person{

      private? Date birthDate;

      public? Person(Date birthDate) {

      this .birthDate = birthDate;

      }

      boolean? isBornBoomer() {

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

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

      return? birthDate.compareTo(startDate)>= 0? && birthDate.compareTo(endDate)

      }

      }

      isBornBoomer是用來這個人是否是1946-1964年出生的,而每次isBornBoomer被調用的時候,都會生成startDate和birthDate兩個對象,造成了空間浪費,如果改成這樣效率會更好:

      ?

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      class? Person{

      private? Date birthDate;

      private? static? Date startDate,endDate;

      static {

      startDate = Date.valueOf( "1946" );

      endDate = Date.valueOf( "1964" );

      }

      public? Person(Date birthDate) {

      this .birthDate = birthDate;

      }

      boolean? isBornBoomer() {

      return? birthDate.compareTo(startDate)>= 0? && birthDate.compareTo(endDate)

      }

      }

      因此,很多時候會將一些只需要進行一次的初始化操作都放在static代碼塊中進行。

      二.static關鍵字的誤區

      1.static關鍵字會改變類中成員的訪問權限嗎?

      有些初學的朋友會將java中的static與C/C++中的static關鍵字的功能混淆了。在這里只需要記住一點:與C/C++中的static不同,Java中的static關鍵字不會影響到變量或者方法的作用域。在Java中能夠影響到訪問權限的只有private、public、protected(包括包訪問權限)這幾個關鍵字。看下面的例子就明白了:

      提示錯誤"Person.age 不可視",這說明static關鍵字并不會改變變量和方法的訪問權限。

      2.能通過this訪問靜態成員變量嗎?

      雖然對于靜態方法來說沒有this,那么在非靜態方法中能夠通過this訪問靜態成員變量嗎?先看下面的一個例子,這段代碼輸出的結果是什么?

      ?

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      public? class? Main {

      static? int? value =? 33 ;

      public? static? void? main(String[] args)? throws? Exception{

      new? Main().printValue();

      }

      private? void? printValue(){

      int? value =? 3 ;

      System.out.println( this .value);

      }

      }

      33

      這里面主要考察隊this和static的理解。this代表什么?this代表當前對象,那么通過new Main()來調用printValue的話,當前對象就是通過new Main()生成的對象。而static變量是被對象所享有的,因此在printValue中的this.value的值毫無疑問是33。在printValue方法內部的value是局部變量,根本不可能與this關聯,所以輸出結果是33。在這里永遠要記住一點:靜態成員變量雖然獨立于對象,但是不代表不可以通過對象去訪問,所有的靜態方法和靜態變量都可以通過對象訪問(只要訪問權限足夠)。

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

      在C/C++中static是可以作用域局部變量的,但是在Java中切記:static是不允許用來修飾局部變量。不要問為什么,這是Java語法的規定。

      三.常見的筆試面試題

      下面列舉一些面試筆試中經常遇到的關于static關鍵字的題目,僅供參考,如有補充歡迎下方留言。

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

      ?

      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

      public? class? Test? extends? Base{

      static {

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

      }

      public? Test(){

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

      }

      public? static? void? main(String[] args) {

      new? Test();

      }

      }

      class? Base{

      static {

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

      }

      public? Base(){

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

      }

      }

      base static test static base constructor test constructor

      瘋狂Java之學習筆記(29)-----------static

      至于為什么是這個結果,我們先不討論,先來想一下這段代碼具體的執行過程,在執行開始,先要尋找到main方法,因為main方法是程序的入口,但是在執行main方法之前,必須先加載Test類,而在加載Test類的時候發現Test類繼承自Base類,因此會轉去先加載Base類,在加載Base類的時候,發現有static塊,便執行了static塊。在Base類加載完成之后,便繼續加載Test類,然后發現Test類中也有static塊,便執行static塊。在加載完所需的類之后,便開始執行main方法。在main方法中執行new Test()的時候會先調用父類的構造器,然后再調用自身的構造器。因此,便出現了上面的輸出結果。

      2.這段代碼的輸出結果是什么?

      ?

      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

      35

      public? class? Test {

      Person person =? new? Person( "Test" );

      static {

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

      }

      public? Test() {

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

      }

      public? static? void? main(String[] args) {

      new? MyClass();

      }

      }

      class? Person{

      static {

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

      }

      public? Person(String str) {

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

      }

      }

      class? MyClass? extends? Test {

      Person person =? new? Person( "MyClass" );

      static {

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

      }

      public? MyClass() {

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

      }

      }

      test static myclass static person static person Test test constructor person MyClass myclass constructor

      類似地,我們還是來想一下這段代碼的具體執行過程。首先加載Test類,因此會執行Test類中的static塊。接著執行new MyClass(),而MyClass類還沒有被加載,因此需要加載MyClass類。在加載MyClass類的時候,發現MyClass類繼承自Test類,但是由于Test類已經被加載了,所以只需要加載MyClass類,那么就會執行MyClass類的中的static塊。在加載完之后,就通過構造器來生成對象。而在生成對象的時候,必須先初始化父類的成員變量,因此會執行Test中的Person person = new Person(),而Person類還沒有被加載過,因此會先加載Person類并執行Person類中的static塊,接著執行父類的構造器,完成了父類的初始化,然后就來初始化自身了,因此會接著執行MyClass中的Person person = new Person(),最后執行MyClass的構造器。

      3.這段代碼的輸出結果是什么?

      ?

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      public? class? Test {

      static {

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

      }

      public? static? void? main(String[] args) {

      }

      static {

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

      }

      }

      test static 1 test static 2

      雖然在main方法中沒有任何語句,但是還是會輸出,原因上面已經講述過了。另外,static塊可以出現類中的任何地方(只要不是方法內部,記住,任何方法內部都不行),并且執行是按照static塊的順序執行的。

      轉載自:https://blog.csdn.net/u011225629/article/details/45664995

      C++ HTTP Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:空白單元格自動填充顏色怎么做(excel快速給空白單元格填充顏色的方法)
      下一篇:【云小課】EI第25課 MRS基礎入門之HBase組件介紹
      相關文章
      亚洲成av人片天堂网| 亚洲香蕉在线观看| 亚洲 日韩经典 中文字幕| 亚洲综合一区二区国产精品| 亚洲国产精品va在线播放| 中文字幕亚洲无线码| 亚洲色图综合在线| 国产国拍亚洲精品福利| 精品亚洲一区二区三区在线播放 | 国产精品亚洲色婷婷99久久精品| 亚洲A∨精品一区二区三区下载| 亚洲丶国产丶欧美一区二区三区| 亚洲宅男精品一区在线观看| 亚洲一区欧洲一区| 最新亚洲卡一卡二卡三新区| 亚洲中文字幕一二三四区| 亚洲狠狠婷婷综合久久蜜芽| 久久综合亚洲色hezyo| 亚洲成AV人在线观看网址| 亚洲国产精品尤物YW在线观看| 爱情岛论坛网亚洲品质自拍| 国产美女亚洲精品久久久综合| 亚洲香蕉成人AV网站在线观看| 亚洲无码精品浪潮| 亚洲一区二区三区香蕉| 亚洲成A∨人片在线观看不卡 | 久久精品国产亚洲av麻| 亚洲男人第一av网站| 亚洲精品在线免费观看| 亚洲一卡2卡3卡4卡国产网站| 中文字幕乱码亚洲精品一区| 亚洲av成人无码网站…| 亚洲日本中文字幕天堂网| 亚洲综合网站色欲色欲| 亚洲AV无码久久| 亚洲欧洲自拍拍偷综合| 亚洲中文字幕精品久久| 国产亚洲人成在线影院| 亚洲热线99精品视频| 亚洲欧洲在线观看| 亚洲熟妇无码久久精品|