Java static 的一兩點使用

来源:http://www.cnblogs.com/qifengshi/archive/2016/07/07/5650230.html
-Advertisement-
Play Games

這篇文章是關於Java static關鍵字的使用,主要會介紹以下的內容: 1. static 的概念 2. static的各種應用 3. 總結 static 是什麼 static 顧名思義是靜態的意思。與this相對,static表示所修飾的部分是屬於類本身所有的,不依賴與某個具體的實例。 而thi ...


這篇文章是關於Java static關鍵字的使用,主要會介紹以下的內容:

  1. static 的概念
  2. static的各種應用
  3. 總結

static 是什麼

static 顧名思義是靜態的意思。與this相對,static表示所修飾的部分是屬於類本身所有的,不依賴與某個具體的實例。 而this上個博客已經講了,可參考this的使用.this表示的是對調用方法的那個當前對象的引用,可以看做是類的實例的引用,依賴於具體的實例。所以這也就是《Java編程思想》裡面說的

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

在瞭解他使用之前,我們先思考一下,為什麼我們需要使用staitc,一切都通過對象去調用不也可以嗎?
這樣做是可以,對象是可以調用實例變數,實例方法,類方法,類成員變數。但是這樣真的好嗎?我們有一些東西是不依賴具體對象。比如我們有一些工具類,如Math,裡面的cos,sin這些都是客觀存在,不會改變的。任何一個對象都不影響Math裡面的任何東西,相反,像我們定義一個圓這個類,那麼圓的半徑,圓的面積顯然是不同的圓 是不同的 這就不能用static。
好了,我們已經知道了static是什麼,以及該什麼時候去使用它,那我們我們都可以怎麼用它呢?

static的用法

  1. static 變數
  2. static 方法
  3. static 代碼塊

static 變數

static變數就是靜態的成員變數,所謂靜態變數就是靜態變數是歸類本身所有,被所有對象所共用,在記憶體中只有一個副本。而非靜態的就是每個對象所有,在記憶體中有多個副本,每個對象的副本互不影響。
比如我們常常自己定義或者是看源碼中有很多常量,這些常量就是用final static修飾的。用static來修飾,讓這個常量不需要new一個對象就能得到,非常的方便。例子如下:

/**
 * Created by byhieg on 2016/6/20.
 */
public class CityFragment extends Fragment {
    public static final String TAG = "CityFragment";
    //省略其他代碼
}

這樣,我們就可以直接通過CityFragment.TAG來得到TAG。

static 方法

static 方法和static 變數的使用目的是一致的,一般用來不通過創建對象來使用方法,用來做工具類的方法。如我們可以把處理字元串的操作的方法統一放到一個固定類裡面,我們調用的時候,只需要通過類名.方法名就可以,省去每次創建對象浪費的記憶體。比如下麵的例子

/**
 * Created by byhieg on 2016/6/20.
 */
public class StringUtils {
    //根據輸入的指定的字元,分割字元串
    public static String[] splitString(String str,String regex) {
        String [] result = str.split(regex);
        return result;
    }

    //刪除指定位置的字元串
    public static String delPosOfString(String str, int[] pos) {
        StringBuffer sb = new StringBuffer(str);
        for(int i = 0 ; i < pos.length;i++) {
            sb.deleteCharAt(pos[i]);
        }
        return sb.toString();
    }
}

我們可以直接這麼調用StringUntils.splitString(args1,args2)
下麵,我們說一些用static 方法的註意事項。我們看一下下麵的例子。

/**
 * Created by byhieg on 2016/6/20.
 */
public class Main {
    public static final String str = "byhieg";
    public String error = "error";

    public void test() {
        System.out.println(str);
        System.out.println(error);
    }

    public static void main(String[] args) {
        System.out.println(test());
        System.out.println(error);
        System.out.println(str);
    }
}

運行會出現下麵的錯誤

Error:(13, 28) java: 無法從靜態上下文中引用非靜態 方法 test()
Error:(14, 28) java: 無法從靜態上下文中引用非靜態 變數 error

雖然我們舉例用的Main方法,但他是static方法,使用的是統一的static語法規則。報錯的原因是因為在靜態方法中我們是無法調用非靜態的成員變數和方法。因為非靜態的方法和變數是依賴於對象創建,對象才能調用的。所以是不可以調用的。但是在非靜態方法中,是可以調用全部,因為上文說了 靜態的是歸所有對象共用,非靜態是省略了this才調用成功的。

/**
 * Created by byhieg on 2016/6/20.
 */
public class Main {
    public static final String str = "byhieg";
    public String error = "error";

    public void test() {
        System.out.println(str);
        System.out.println(error);
        //此處省略了this 實際應該是this.test1(),this.error
        //所以也是通過對象對調用的非靜態的變數和方法
        test1();
    }


    public void test1() {
        System.out.println(str);
        System.out.println(error);
    }
    public static void main(String[] args) {
        new Main().test();
    }
}

static 初始化塊

在說明靜態初始化塊的時候,我們先瞭解一下什麼是初始化塊。當我們需要生成很多對象的時候,每次都需要執行構造方法,如果我們的構造方法中,有一些代碼是不依賴參數的,我們就可以把這些代碼提取出來,放到同一個地方。這個地方我們稱之為初始化塊。
初始化塊允許定義很多個,執行順序與書寫的順序有關,但實際沒什麼卵用,因為他是創建Java對象時隱式執行,且全部被執行,完全可以把他們放到一起去執行。初始化塊的執行會先於構造器,這點很重要。
接下來,我們看一下static靜態塊,static靜態塊除了有靜態塊的優點以外,他還有static所帶來的優點,即他在類初次被載入時執行,且只會執行一次。不會像普通代碼塊一樣,每次對象創建時都會執行,這樣我們可以把一些造成空間浪費的語句,放到靜態初始化塊中執行。比如下麵的代碼

/**
 * Created by byhieg on 2016/6/20.
 */
public class Main {
    
    public Main() {
        Integer a = new Integer(1024);
        //省略其他初始化代碼
        
    }
}

每次在new一個新對象的時候,都會創建一個新的Integer對象。這樣無疑浪費空間,這時我們就需要用靜態代碼塊,把Integer a放進去,就可以保證只會初始化一次。如下:

/**
 * Created by byhieg on 2016/6/20.
 */
public class Main {
    public static Integer a;
    
    static {
        a = new Integer(1024);
    }

    public Main() {
        //省略構造器其他代碼
    }
}

靜態初始化塊執行的順序在普通初始化塊執行之前,因為只有類被載入並初始化之後,我們才能創建類的的實例,但以後再創建的實例的時候就不會再執行靜態初始化塊了。

總結

static 是與類相關的一個關鍵字,所修飾的部分表明該部分是歸類所有。比如static修飾變數就表明該變數是靜態變數,被所有對象所共用,被類所擁有。static修飾方法,與變數時一致的,只是在靜態方法中是不允許調用非靜態的變數和方法。而靜態代碼塊是比較特殊的存在,用來初始化一些共有的東西,在類被載入時只執行一次。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上述代碼編譯運行皆沒有問題,但是用valgrind檢測會提示錯誤: Why? 此代碼可以實現功能要求,但是健壯性並不好,假設在map.erase之後再次使用map當前的iterator,即 代碼運行就會出現錯誤,因為it目前指向的對象已經被刪掉了。 為了避免程式出現這樣的錯誤,我們應該保證在iter ...
  • 徒手使用python和go語言搭建最簡單的web頁面-使用模板,無持久化 也許我們會接觸到很多語言的web應用,譬如php,java,包括今天介紹的python和go,實際上我們在使用這些語言構建web應用的時候,很多時候變成了單純的調用包和api,而忽略底層的原理。不過呢,所有的web應用,模型都 ...
  • 異常是什麼,它是怎麼發生的?Java系統是怎麼處理的,和正常return有什麼區別?應用程式能如何處理?Throwable是什麼,它有哪些屬性和方法?Java都有哪些異常類,有什麼區別,為什麼要那麼多類?... ...
  • scalaz-stream是一個泛函數據流配件庫(functional stream combinator library),特別適用於函數式編程。scalar-stream是由一個以上各種狀態的Process串聯組成。stream代表一連串的元素,可能是自動產生或者由外部的源頭輸入,如:一連串滑鼠 ...
  • php中一個"異類"語法: $a && $b = $c; php中一個"異類"語法: $a && $b = $c; $a = 1;$b = 2;$c = 3;$a && $b = $c;echo "a:$a";echo "b:$b";echo "c:$c";這樣是a:1b:3c:3$a = 0;$b ...
  • eclispe中,點擊調試運行java項目,出現 cannot connect to VM 正常的運行項目,沒問題; 以為是jdk的安裝路徑等的問題,還有殺毒軟體等等,都沒有正常; 後來找到是winsock出問題了,運行cmd ,在命令行中執行 netsh winsock reset 再重啟機器,果 ...
  • ③最後將B上的1個圓盤移到C上。 ★★★有了代碼就好辦了★★★ 代碼奉上▼ 關於C++與Dev-C++的下載 ...
  • 後續補充更新 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...