這篇文章是關(guān)于Java static關(guān)鍵字的使用召锈,主要會介紹以下的內(nèi)容:
- static 的概念
- static的各種應(yīng)用
- 總結(jié)
static 是什么
static 顧名思義是靜態(tài)的意思都哭。與this相對结耀,static表示所修飾的部分是屬于類本身所有的浩嫌,不依賴與某個具體的實例孵稽。 而this上個博客已經(jīng)講了,可參考this的使用.this表示的是對調(diào)用方法的那個當(dāng)前對象的引用罩润,可以看做是類的實例的引用赫舒,依賴于具體的實例延旧。所以這也就是《Java編程思想》里面說的
“static方法就是沒有this的方法谋国。在static方法內(nèi)部不能調(diào)用非靜態(tài)方法,反過來是可以的迁沫。而且可以在沒有創(chuàng)建任何對象的前提下,僅僅通過類本身來調(diào)用static方法捌蚊。這實際上正是static方法的主要用途集畅。”
在了解他使用之前缅糟,我們先思考一下挺智,為什么我們需要使用staitc,一切都通過對象去調(diào)用不也可以嗎窗宦?
這樣做是可以赦颇,對象是可以調(diào)用實例變量,實例方法赴涵,類方法媒怯,類成員變量。但是這樣真的好嗎髓窜?我們有一些東西是不依賴具體對象扇苞。比如我們有一些工具類,如Math
寄纵,里面的cos鳖敷,sin
這些都是客觀存在,不會改變的程拭。任何一個對象都不影響Math里面的任何東西定踱,相反,像我們定義一個圓這個類恃鞋,那么圓的半徑崖媚,圓的面積顯然是不同的圓 是不同的 這就不能用static。
好了山宾,我們已經(jīng)知道了static是什么至扰,以及該什么時候去使用它,那我們我們都可以怎么用它呢资锰?
static的用法
- static 變量
- static 方法
- static 代碼塊
static 變量
static變量就是靜態(tài)的成員變量敢课,所謂靜態(tài)變量就是靜態(tài)變量是歸類本身所有,被所有對象所共享,在內(nèi)存中只有一個副本直秆。而非靜態(tài)的就是每個對象所有濒募,在內(nèi)存中有多個副本,每個對象的副本互不影響圾结。
比如我們常常自己定義或者是看源碼中有很多常量瑰剃,這些常量就是用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 變量的使用目的是一致的,一般用來不通過創(chuàng)建對象來使用方法焕议,用來做工具類的方法宝磨。如我們可以把處理字符串的操作的方法統(tǒng)一放到一個固定類里面,我們調(diào)用的時候盅安,只需要通過類名.方法名
就可以唤锉,省去每次創(chuàng)建對象浪費的內(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 方法的注意事項窿祥。我們看一下下面的例子。
/**
* 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);
}
}
運行會出現(xiàn)下面的錯誤
Error:(13, 28) java: 無法從靜態(tài)上下文中引用非靜態(tài) 方法 test()
Error:(14, 28) java: 無法從靜態(tài)上下文中引用非靜態(tài) 變量 error
雖然我們舉例用的Main方法畜隶,但他是static方法壁肋,使用的是統(tǒng)一的static語法規(guī)則。報錯的原因是因為在靜態(tài)方法中我們是無法調(diào)用非靜態(tài)的成員變量和方法籽慢。因為非靜態(tài)的方法和變量是依賴于對象創(chuàng)建浸遗,對象才能調(diào)用的。所以是不可以調(diào)用的箱亿。但是在非靜態(tài)方法中跛锌,是可以調(diào)用全部,因為上文說了 靜態(tài)的是歸所有對象共享届惋,非靜態(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 實際應(yīng)該是this.test1(),this.error
//所以也是通過對象對調(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)初始化塊的時候,我們先了解一下什么是初始化塊脑豹。當(dāng)我們需要生成很多對象的時候郑藏,每次都需要執(zhí)行構(gòu)造方法,如果我們的構(gòu)造方法中瘩欺,有一些代碼是不依賴參數(shù)的必盖,我們就可以把這些代碼提取出來拌牲,放到同一個地方。這個地方我們稱之為初始化塊歌粥。
初始化塊允許定義很多個塌忽,執(zhí)行順序與書寫的順序有關(guān),但實際沒什么卵用失驶,因為他是創(chuàng)建Java對象時隱式執(zhí)行土居,且全部被執(zhí)行,完全可以把他們放到一起去執(zhí)行嬉探。初始化塊的執(zhí)行會先于構(gòu)造器擦耀,這點很重要。
接下來涩堤,我們看一下static靜態(tài)塊埂奈,static靜態(tài)塊除了有靜態(tài)塊的優(yōu)點以外,他還有static所帶來的優(yōu)點定躏,即他在類初次被加載時執(zhí)行,且只會執(zhí)行一次芹敌。不會像普通代碼塊一樣痊远,每次對象創(chuàng)建時都會執(zhí)行,這樣我們可以把一些造成空間浪費的語句氏捞,放到靜態(tài)初始化塊中執(zhí)行碧聪。比如下面的代碼
/**
* Created by byhieg on 2016/6/20.
*/
public class Main {
public Main() {
Integer a = new Integer(1024);
//省略其他初始化代碼
}
}
每次在new一個新對象的時候,都會創(chuàng)建一個新的Integer對象液茎。這樣無疑浪費空間逞姿,這時我們就需要用靜態(tài)代碼塊,把Integer a放進(jìn)去捆等,就可以保證只會初始化一次滞造。如下:
/**
* 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í)行之前,因為只有類被加載并初始化之后栋烤,我們才能創(chuàng)建類的的實例谒养,但以后再創(chuàng)建的實例的時候就不會再執(zhí)行靜態(tài)初始化塊了。
總結(jié)
static 是與類相關(guān)的一個關(guān)鍵字明郭,所修飾的部分表明該部分是歸類所有买窟。比如static修飾變量就表明該變量是靜態(tài)變量,被所有對象所共享薯定,被類所擁有始绍。static修飾方法,與變量時一致的话侄,只是在靜態(tài)方法中是不允許調(diào)用非靜態(tài)的變量和方法亏推。而靜態(tài)代碼塊是比較特殊的存在学赛,用來初始化一些共有的東西,在類被加載時只執(zhí)行一次径簿。