Java下static關鍵字用法詳解
本文章介紹了java下static關鍵字的用法,大部分內容摘自原作者,在此學習并分享給大家。
Static關鍵字可以修飾什么?
從以下測試可以看出, static 可以修飾:
1. 語句塊
2. 成員變量(但是不能修飾局部變量)
3. 方法
4. 接口(內部接口)
5. 類(只能修飾在類中的類, 即靜態(tài)內部類)
6. jdk 1.5 中新增的靜態(tài)導入
那么static 修飾的表示什么呢? 當創(chuàng)建一個類時,就是在創(chuàng)建一個新類型,描述這個類的對象的外觀和行為,除非用new創(chuàng)建出那個類的對象,數(shù)據存儲空間才被分配,其方法才供外界調用。那么當聲明一個事物為static時,就意味著這個域或者方法不會與包含它的那個類的任何對象關聯(lián)在一起,也就是說,它不依賴類特定的實例,被類的所有實例共享,只要這個類被加載,Java虛擬機就能根據類名在運行時數(shù)據區(qū)的方法區(qū)內定找到他們。因此,static對象可以在它的任何對象創(chuàng)建之前訪問,無需引用任何對象。
1. static 修飾語句塊:
static{} 可以有多處,執(zhí)行順序按照他們的聲明順序。當JVM加載這個類的時候,就會執(zhí)行此語句塊,并且只執(zhí)行一次。
2. static 變量:
static 變量,可以被類的所有對象共享,并且它只有一份存儲空間,JVM只為靜態(tài)分配一次內存,在加載類的過程中完成靜態(tài)變量的內存分配。那么在引用static變量的時候,使用(類名.變量名)是首選的方式,因為他不僅強調它是static結構,而且在某些情況下會為編譯器進行優(yōu)化提供更好的機會。
使用類名直接引用static變量是比較力薦的,這樣就很明確的告訴大家該變量或屬性是static結構或是被static修飾。
但是我想說一個更重要的知識點。static 在類中當變量的重要使用方法,首先樓主先運行一下下面代碼試試:
public class Person {
static int[] arr = new int[3];
public static void main(String[] args){
Person per1 = new Person();
Person per2 = new Person();
Person per3 = new Person();
System.out.println("----改變之前-----");
System.out.print("per1-->");
per1.show();
System.out.print("per2-->");
per2.show();
System.out.print("per3-->");
per3.show();
//現(xiàn)在我改變它的值
Person.arr[2]=10;//這種方法是建議的
per1.arr[0]=1;//一般不用這種方法
System.out.println("----改變之后-----");
System.out.print("per1-->");
per1.show();
System.out.print("per2-->");
per2.show();
System.out.print("per3-->");
per3.show();
}
//為了方便,封裝一個方法,來解釋
public void show(){
for(int i=0; i
System.out.print(arr[i] + "t");
}
System.out.println("");
}
}Output:
----改變之前-----
per1-->0t0t0t
per2-->0t0t0t
per3-->0t0t0t
----改變之后-----
per1-->1t0t10t
per2-->1t0t10t
per3-->1t0t10t
類似的形式同樣應用在使用static修飾的方法上面(稱為靜態(tài)方法)。它可以像普通方法一樣使用對象來引用,也可以通過特殊的語法形式來調用如:“類名”+“ . ”+“方法”(); 定義靜態(tài)方法的方式與定義靜態(tài)變量一樣:
public class StaticTest2 {
static void method(){ ("這是靜態(tài)方法"); }
}
普通的調用方法:StaticTest2 st = new StaticTest2(); 因為method是static修飾的(靜態(tài)方法),所以可以這樣調用:StaticTest2.()。
3. static方法:
static方法與非static方法的區(qū)別在于: static方法可以用類名直接訪問在static內部的變量和方法,而不能引用非static的變量或者方法,但是你可以通過傳遞參數(shù)的方式傳遞一個引用,讓這個引用去調用非靜態(tài)數(shù)據。
4. static 接口:
內部接口(inner interface)本身就默認是static,所以static關鍵詞加與不加都是一樣的, 如此例中的接口:TestInInterface,TestInClass 實現(xiàn)此接口, 以下語句:
StaticDescription.TestInInterface a = new StaticDescription.TestInClass();
a.print();
我們去掉static關鍵字也是一樣的, 但還是受訪問權限控制TestInterface和FF。
5. static 修飾類:
表示它是一個靜態(tài)內部類,它在引用外部類的事物時,必須也是static的。而且, 靜態(tài)內部類在創(chuàng)建自己的對象時, 是不需要外圍類的存在。就好像下面的部分:
class Member {
static int classVar = 0; //類變量
int instanceVar; //實例變量
Member(int instanceVar) {
this.instanceVar = instanceVar;
}
static void setClassVar(int i) {
classVar=i;
//instanceVar=i; // 類方法不能訪問實例變量,只能訪問類變量
}
static int getClassVar() {//類方法
return classVar;
}
void setInstanceVar(int i) {
classVar=i; //實例方法不但可以訪問類變量,也可以實例變量
instanceVar=i;
}
int getInstanceVar() {
return instanceVar;
}
}
Member未實例化: Member實例化之后:
1
對于非靜態(tài)數(shù)據成員,每個類對象都有自己的拷貝。而靜態(tài)數(shù)據成員被當作是類的成員。無論這個類的對象被定義了多少個,靜態(tài)數(shù)據成員在程序中也只有一份拷貝,由該類型的所有對象共享訪問。也就是說,靜態(tài)數(shù)據成員是該類的所有對象所共有的。對該類的多個對象來說,靜態(tài)數(shù)據成員只分配一次內存,供所有對象共用。所以,靜態(tài)數(shù)據成員的值對每個對象都是一樣的,它的值可以更新托福答案
Member m1 = new Member();
Member m2 = new Member();
內存分配
2
引用static變量有兩種方法。如前例所示,可以通過一個對象去定位它,如m1.classVar; 也可以通過其類名直接引用,如Member.classVar,而對于非靜態(tài)成員則不行。
盡管當static作用于某個字段時,肯定會改變數(shù)據的創(chuàng)建方式(因為一個static字段對每個類來說都只有一份存儲空間,而非static字段則是對每個對象都有一個存儲空間),但是如果static用于某個方法,差別卻沒有那么大。static方法的一個重要用法就是在不創(chuàng)建任何對象的前提下就可以調用它。這一點,對定義main()方法很重要,這個方法是運行一個應用時的入口點。
static方法就是沒有this的方法。在static方法的內部不能調用非靜態(tài)方法,反過來倒是可以的。而且可以在沒有創(chuàng)建任何對象的前提下,僅僅通過類本身來調用static方法。這實際上正是static方法的主要用途。它很像全局方法。Java中禁止使用全局方法,但你在類中置入static方法就可以訪問其他static方法和static域托福答案
和其他任何方法一樣,static方法可以創(chuàng)建或使用與其類型相同的被命名對象,因此,static方法通常拿來做“牧羊人”的角色,負責看護與其奴隸同一類型的實例群。
不過,要是在代碼中出現(xiàn)大量的static方法,就該重新考慮自己的設計了