JAVA中的static 關鍵字
本章主要對static關鍵字做些介紹以及static關鍵字的基本用法。
- static關鍵字的概念
- 靜態變量,靜態方法
- 靜態代碼塊
- 靜態導入
- 靜態類
- static與修飾符連用
- 代碼舉例
static關鍵字的概念
static在java中到底代表什麼,爲何要用它?
static――靜態――“指定位置“
首先,我們來看看java的內存:java把內存分爲棧內存和堆內存,棧內存用來存放一些基本類型的變量和數組及對象的引用變量,而堆內存主要是來放置對象的。
用static的修飾的變量和方法,實際上是指定了這些變量和方法在內存中的“固定位置”-static storage。既然要有“固定位置”那麼他們的 “大小”似乎就是固定的了,有了固定位置和固定大小的特徵了,在棧中或堆中開闢空間那就是非常的方便了。如果靜態的變量或方法在不出其作用域的情況下,其 引用句柄是不會發生改變的。
我們常看到:static變 量有點類似於C中的全局變量的概念;靜態表示的是內存的共享,就是它的每一個 實例都指向同一個內存地址。把static拿來,就是告訴JVM它是靜態的,它的引用(含間接引用)都是指向同一個位置,在那個地方,你把它改了,它就不 會變成原樣,你把它清理了,它就不會回來了。
靜態變量,靜態方法
static修飾的成員變量和成員方法習慣上稱爲靜態變量和靜態方法,可以直接通過類名來訪問,訪問語法爲:
類名.靜態方法名(參數列表…)
被static修飾的成員變量和成員方法獨立於該類的任何對象。也就是說,它不依賴類特定的實例,被類的所有實例共享。
只要這個類被加載,Java虛擬機就能根據類名在運行時數據區的方法區內定找到他們。因此,static對象可以在它的任何對象創建之前訪問,無需引用任何對象。
靜態方法中只能訪問靜態的成員變量。
static 代碼塊
static代碼塊也叫靜態代碼塊,是在類中獨立於類成員的static語句塊,可以有多個,位置可以隨便放,它不在任何的方法體內,JVM加載類時會執行這些靜態的代碼塊,如果static代碼塊有多個,JVM將按照它們在類中出現的先後順序依次執行它們,每個代碼塊只會被執行一次。
靜態導入
java中可以通過import 導入需要用到的類和包。也可以通過靜態導入導入靜態方法,這樣就可以直接使用導入類中的方法,而不需要通過【類.方法名】的方式使用靜態方法。
靜態類(靜態內部類)
靜態內部類是指在一個類的內部,又定義了一個用static修飾的類。可以用C中的結構體內嵌結構體來理解。
A,首先,用內部類是因爲內部類與所在外部類有一定的關係,往往只有該外部類調用此內部類。所以沒有必要專門用一個Java文件存放這個類。
B,靜態方法、靜態成員變量。它唯一的作用就是隨着類的加載(而不是隨着對象的產生)而產生,以致可以用類名+靜態成員名直接獲得。
C, 靜態類只能有靜態內部類,外部類若定義爲靜態的,會報編譯錯誤。
- static與修飾符連用
-
與public連用
當static與public連用時,表示該成員變量或者方法可以被共享,其他的類中可以通過【類名.方法名/成員變量名】的 方式訪問到此靜態方法/變量
-
與private連用
當靜態成員變量與private連用時,表示該靜態成員變量只能被本類的靜態方法調用,不能被其他的類訪問。
- 與final連用
當static與final 同時用於修飾成員變量時,表明該靜態成員變量被賦值後,該靜態成員變量的值不會發生改變。注:此處靜態成員變量的值不會發生改變表現爲,若該靜態變量是8大基本類型,則該靜態變量的值不再發生改變,當靜態成員變量爲對象時,表示該靜態變量始終指向同一個對象。
代碼舉例
靜態成員變量
public class Example{
public static int count;
public static String name;
public static boolean isStudent;
}
靜態方法
package com.moxuelang.static;
public class Example{
public static int count;
public static int getCount(){
return count;
}
public static String name;
public static String getName(){
return name;
}
}
static 代碼塊
package com.moxuelang.static;
public class Example{
public static int count;
public static int getCount(){
return count;
}
public static String name;
public static String getName(){
return name;
}
static{//與順序無關
count = 1;
name ="moxuelang";
}
}
靜態導入
package com.moxuelang.static;
//導入Example類的靜態方法
import static com.moxuelang.static.Example.getName;
//導入Example 類的靜態成員變量
import static com.moxuelang.static.Example.name;
public class Example2{
public String getExampleName(){
return name;//直接使用Example中的名字
}
public String getExampleName2(){
return getName();//直接使用Example中的方法名
}
}
需要說明的是,如果Example2中重新定義了name變量和getName方法,Example2將不能直接使用Example中的name和getName,即靜態導入無用。
靜態類(靜態內部類)
package com.moxuelang.static;
public class Build {
public static class VERSION {
public static final String RELEASE=getString("ro.build.version.release");
public static String getString(String str){
return "static output:"+str;
}
}
public static void main(String[] args){
System.out.println(Build.VERSION.RELEASE);
}
}