隨筆-126  評論-247  文章-5  trackbacks-0


          前言:這屬于 java 的基礎知識,你可以不了解,也可以不拿它當一回事,代碼也一樣能敲的順暢;這是很久之前,我從 C++ 轉 java 剛入門那會的看法,那會我堅持自己的理念:
              重實踐,講運用,輕理論。當然,對同一樣事物,在不同階段也會有不一樣的看法,這理念在某個時段已經不適合我,早就被拋棄了。不扯淡了,直接進入主題。

          java 中的變量大致分為 成員變量 和 局部變量 兩大類。

          成員變量:
              在類體里面定義的變量稱為成員變量;
              如果該成員變量有 static 關鍵字修飾,則該成員變量稱為 靜態變量類變量
              如果該成員變量沒有 static 關鍵字修飾,則該成員變量被稱為 非靜態變量實例變量

          局部變量:
              形參、方法內定義的變量、代碼塊中定義的變量,都屬于局部變量。

          類變量 (靜態變量
              1. 可以向前引用
              2. 變量屬于類本身
              3. 類變量不依賴類的實例,類變量只在初始化時候在棧內存中被分配一次空間,無論類的實例被創建幾次,都不再為類變量分配空間
              4. 通過類的任意一個實例來訪問類變量,底層都將將其轉為通過類本身來訪問類變量,它們的效果是一樣的
              5. 一旦類變量的值被改變,通過類或類的任意一個實例來訪問類變量,得到的都將是被改變后的值
              6. 將在類的初始化之前初始化

          實例變量(非靜態變量)
              1. 不能向前引用,如果向前引用,則稱為非法向前引用,這是不允許的
              2. 變量屬于類的實例對象
              3. 隨著類的實例被創建而分配內存空間

          非靜態代碼塊
              直接由 { } 包起來的代碼,稱為非靜態代碼塊

          靜態代碼塊
              直接由 static { } 包起來的代碼,稱為靜態代碼塊

          類變量(靜態變量)、實例變量(非靜態變量)、靜態代碼塊、非靜態代碼塊 的初始化時機
              由 static 關鍵字修飾的(如:類變量[靜態變量]、靜態代碼塊)將在類被初始化創建實例對象之前被初始化,而且是按順序從上到下依次被執行;
              沒有 static 關鍵字修飾的(如:實例變量[非靜態變量]、非靜態代碼塊)初始化實際上是會被提取到類的構造器中被執行的,但是會比類構造器中的
              代碼塊優先執行到,其也是按順序從上到下依次被執行。

          - 以上是本人在翻完 PDF 后的個人筆記和理解以及見解,不見得百分百對,以下附上本人測試示例代碼,會更有說服性

          示例代碼

           1
           2/**
           3 * -----------------------------------------
           4 * @文件: Statical.java
           5 * @作者: fancy
           6 * @郵箱: fancydeepin@yeah.net
           7 * @時間: 2012-7-9
           8 * @描述: TEST
           9 * -----------------------------------------
          10 */

          11public class Statical {
          12
          13 /**
          14     * 靜態代碼塊
          15     * 類變量(靜態變量)可以向前引用(即:先引用,再定義)
          16     */

          17    static {
          18        name = "fancydeepin"// name 的定義在使用之后
          19        System.out.println("--->  靜態代碼塊被執行   <---");
          20    }

          21 /**
          22     * 類變量(靜態變量)在類的初始化之前初始化,無論類的實例將被創建多少個
          23     * 類變量(靜態變量)都將只在初始化時候在棧內存上分配一次空間
          24     * 凡 static 修飾的,都將按位置被順序執行,所以,
          25     * name 的值最終輸出 fancy 而不是上面的 fancydeepin
          26     */

          27    public static String name = "fancy"//類變量(靜態變量)
          28    private String mail = "myEmail"//實例變量(非靜態變量),定義時指定初始值,會比在構造器賦予值更早執行
          29    
          30    public Statical() {
          31        mail = "fancydeepin@yeah.net";
          32        System.out.println("---> 構造器代碼塊被執行 <---");
          33    }

          34 /**
          35     * 非靜態代碼塊
          36     * 實際上,非靜態代碼塊在類初始化創建實例時,將會被提取到類的構造器中,
          37     * 但是,非靜態代碼塊會比構造器中的代碼塊優先被執行
          38     * 所以,mail 最終輸出的是類構造器中給定的值,也就是 fancydeepin@yeah.net
          39     * 而不是 1525336367@qq.com,更不是 myEmail
          40     */

          41    {
          42        mail = "1525336367@qq.com";
          43        System.out.println("---> 非靜態代碼塊被執行 <---");
          44    }

          45    
          46    // getting and setting 
          47


          測試類示例代碼

           1
           2      /**
           3         * 類變量(靜態變量)在類被初始化創建實例之前被初始化
           4         */

           5        System.out.println("-----------------> @1 <----------------");
           6        System.out.println("name --->> " + Statical.name); // @1
           7        System.out.println("-----------------> @1 <----------------");
           8       /**
           9         * 創建類的實例對象
          10         */

          11        System.out.println("-----------------> @6 <----------------");
          12        Statical statical = new Statical(); // @6
          13        System.out.println("-----------------> @6 <----------------");
          14        /**
          15         * 通過實例來訪問類變量,底層將轉化成通過類本身來訪問類變量
          16         */

          17        System.out.println("-----------------> @2 <----------------");
          18        System.out.println("name --->> " + statical.name); // @2
          19        System.out.println("-----------------> @2 <----------------");
          20       /**
          21         * 如果類變量的值被改變,再訪問類變量,將得到被改變后的值
          22         */

          23        Statical.name = "fancydeepin";
          24        
          25        System.out.println("-----------------> @3 <----------------");
          26        System.out.println("name --->> " + statical.name); // @3
          27        System.out.println("-----------------> @3 <----------------");
          28        
          29        System.out.println("-----------------> @4 <----------------");
          30        System.out.println("name --->> " + Statical.name); // @4
          31        System.out.println("-----------------> @4 <----------------");
          32       /**
          33         * 非靜態代碼塊 和 構造器 被執行的時機
          34         */

          35        System.out.println("-----------------> @5 <----------------");
          36        System.out.println("mail --->> " + statical.getMail()); // @5
          37        System.out.println("-----------------> @5 <----------------");
          38


          后臺輸出結果


          -----------------> @1 <----------------
          --->  靜態代碼塊被執行   <---
          name 
          --->> fancy
          -----------------> @1 <----------------

          -----------------> @6 <----------------
          ---> 非靜態代碼塊被執行 <---
          ---> 構造器代碼塊被執行 <---
          -----------------> @6 <----------------

          -----------------> @2 <----------------
          name 
          --->> fancy
          -----------------> @2 <----------------

          -----------------> @3 <----------------
          name 
          --->> fancydeepin
          -----------------> @3 <----------------

          -----------------> @4 <----------------
          name 
          --->> fancydeepin
          -----------------> @4 <----------------

          -----------------> @5 <----------------
          mail 
          --->> fancydeepin@yeah.net
          -----------------> @5 <----------------



          為了能更好的看出后臺的輸出是哪一行代碼執行的結果,我用了 @和數字來做了標記,希望大家不要看暈了哈 ^_^
          最后針對輸出結果簡單說一下:
          @1 說明,靜態(類變量、靜態代碼塊)屬于類本身,不依賴于類的實例
          @6 說明,在創建類的實例對象的時候,非靜態代碼塊比構造器代碼塊更早的執行
          @3 4 說明,當類變量的值改變后,再通過類或類的實例來訪問類變量,得到的將是被改變后的值
          @5 說明,非靜態(實例變量、非靜態代碼塊)的地位是相等的,它們將按順序被執行,但會比構造器中的代碼塊更早的執行




            
          posted on 2012-07-09 19:55 fancydeepin 閱讀(12355) 評論(3)  編輯  收藏

          評論:
          # re: java 中的 成員變量、局部變量、靜態變量、類變量、非靜態變量、實例變量、向前引用、非法向前引用、靜態代碼塊、非靜態代碼塊 執行時機[未登錄] 2014-01-10 16:58 | 陽光
          類變量只被加載到方法區,而不是棧內存  回復  更多評論
            
          # re: java 中的 成員變量、局部變量、靜態變量、類變量、非靜態變量、實例變量、向前引用、非法向前引用、靜態代碼塊、非靜態代碼塊 執行時機 2014-02-14 10:52 | colorain
          請問一個問題

          類的成員變量,不能夠在類中使用 這是為什么呢
          比如

          class Test{
          private List list = new ArrayList();
          list.add("abc");// 在這里是不能使用 list變量的 原因是什么呢?


          }  回復  更多評論
            
          # re: java 中的 成員變量、局部變量、靜態變量、類變量、非靜態變量、實例變量、向前引用、非法向前引用、靜態代碼塊、非靜態代碼塊 執行時機[未登錄] 2015-05-24 18:07 | Kevin
          @colorain
          它是需要在方法中執行的。  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 和平县| 盐亭县| 中牟县| 清新县| 海宁市| 贵州省| 绥化市| 荆州市| 育儿| 呼伦贝尔市| 长宁县| 韩城市| 乌恰县| 辉南县| 四川省| 巫溪县| 昭觉县| 博兴县| 大英县| 北流市| 北安市| 淮滨县| 岳西县| 精河县| 虞城县| 南宫市| 益阳市| 九江县| 延长县| 太湖县| 韩城市| 东港市| 安多县| 洛宁县| 巫溪县| 红河县| 大兴区| 阳城县| 康保县| 河间市| 昌图县|