Java static 的一兩點(diǎn)使用

這篇文章是關(guān)于Java static關(guān)鍵字的使用,主要會(huì)介紹以下的內(nèi)容:

  1. static 的概念
  2. static的各種應(yīng)用
  3. 總結(jié)

static 是什么

static 顧名思義是靜態(tài)的意思。與this相對(duì),static表示所修飾的部分是屬于類本身所有的,不依賴與某個(gè)具體的實(shí)例。 而this上個(gè)博客已經(jīng)講了,可參考this的使用.this表示的是對(duì)調(diào)用方法的那個(gè)當(dāng)前對(duì)象的引用,可以看做是類的實(shí)例的引用,依賴于具體的實(shí)例。所以這也就是《Java編程思想》里面說的

“static方法就是沒有this的方法。在static方法內(nèi)部不能調(diào)用非靜態(tài)方法,反過來是可以的。而且可以在沒有創(chuàng)建任何對(duì)象的前提下,僅僅通過類本身來調(diào)用static方法。這實(shí)際上正是static方法的主要用途?!?/p>

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

static的用法

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

static 變量

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

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

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

static 方法

static 方法和static 變量的使用目的是一致的,一般用來不通過創(chuàng)建對(duì)象來使用方法,用來做工具類的方法。如我們可以把處理字符串的操作的方法統(tǒng)一放到一個(gè)固定類里面,我們調(diào)用的時(shí)候,只需要通過類名.方法名就可以,省去每次創(chuàng)建對(duì)象浪費(fèi)的內(nèi)存。比如下面的例子

/**
 * Created by byhieg on 2016/6/20.
 */
public class StringUtils {
    //根據(jù)輸入的指定的字符,分割字符串
    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();
    }
}

我們可以直接這么調(diào)用StringUntils.splitString(args1,args2)
下面,我們說一些用static 方法的注意事項(xiàng)。我們看一下下面的例子。

/**
 * 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);
    }
}

運(yùn)行會(huì)出現(xiàn)下面的錯(cuò)誤

Error:(13, 28) java: 無(wú)法從靜態(tài)上下文中引用非靜態(tài) 方法 test()
Error:(14, 28) java: 無(wú)法從靜態(tài)上下文中引用非靜態(tài) 變量 error

雖然我們舉例用的Main方法,但他是static方法,使用的是統(tǒng)一的static語(yǔ)法規(guī)則。報(bào)錯(cuò)的原因是因?yàn)樵陟o態(tài)方法中我們是無(wú)法調(diào)用非靜態(tài)的成員變量和方法。因?yàn)榉庆o態(tài)的方法和變量是依賴于對(duì)象創(chuàng)建,對(duì)象才能調(diào)用的。所以是不可以調(diào)用的。但是在非靜態(tài)方法中,是可以調(diào)用全部,因?yàn)樯衔恼f了 靜態(tài)的是歸所有對(duì)象共享,非靜態(tài)是省略了this才調(diào)用成功的。

/**
 * 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 實(shí)際應(yīng)該是this.test1(),this.error
        //所以也是通過對(duì)象對(duì)調(diào)用的非靜態(tài)的變量和方法
        test1();
    }


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

static 初始化塊

在說明靜態(tài)初始化塊的時(shí)候,我們先了解一下什么是初始化塊。當(dāng)我們需要生成很多對(duì)象的時(shí)候,每次都需要執(zhí)行構(gòu)造方法,如果我們的構(gòu)造方法中,有一些代碼是不依賴參數(shù)的,我們就可以把這些代碼提取出來,放到同一個(gè)地方。這個(gè)地方我們稱之為初始化塊。
初始化塊允許定義很多個(gè),執(zhí)行順序與書寫的順序有關(guān),但實(shí)際沒什么卵用,因?yàn)樗莿?chuàng)建Java對(duì)象時(shí)隱式執(zhí)行,且全部被執(zhí)行,完全可以把他們放到一起去執(zhí)行。初始化塊的執(zhí)行會(huì)先于構(gòu)造器,這點(diǎn)很重要。
接下來,我們看一下static靜態(tài)塊,static靜態(tài)塊除了有靜態(tài)塊的優(yōu)點(diǎn)以外,他還有static所帶來的優(yōu)點(diǎn),即他在類初次被加載時(shí)執(zhí)行,且只會(huì)執(zhí)行一次。不會(huì)像普通代碼塊一樣,每次對(duì)象創(chuàng)建時(shí)都會(huì)執(zhí)行,這樣我們可以把一些造成空間浪費(fèi)的語(yǔ)句,放到靜態(tài)初始化塊中執(zhí)行。比如下面的代碼

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

每次在new一個(gè)新對(duì)象的時(shí)候,都會(huì)創(chuàng)建一個(gè)新的Integer對(duì)象。這樣無(wú)疑浪費(fèi)空間,這時(shí)我們就需要用靜態(tài)代碼塊,把Integer a放進(jìn)去,就可以保證只會(huì)初始化一次。如下:

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

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

靜態(tài)初始化塊執(zhí)行的順序在普通初始化塊執(zhí)行之前,因?yàn)橹挥蓄惐患虞d并初始化之后,我們才能創(chuàng)建類的的實(shí)例,但以后再創(chuàng)建的實(shí)例的時(shí)候就不會(huì)再執(zhí)行靜態(tài)初始化塊了。

總結(jié)

static 是與類相關(guān)的一個(gè)關(guān)鍵字,所修飾的部分表明該部分是歸類所有。比如static修飾變量就表明該變量是靜態(tài)變量,被所有對(duì)象所共享,被類所擁有。static修飾方法,與變量時(shí)一致的,只是在靜態(tài)方法中是不允許調(diào)用非靜態(tài)的變量和方法。而靜態(tài)代碼塊是比較特殊的存在,用來初始化一些共有的東西,在類被加載時(shí)只執(zhí)行一次。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容