J2SE入門(六) static五大應用場景
static和final是兩個我們必須掌握的關鍵字。不同於其他關鍵字,他們都有多種用法,而且在一定環境下使用,可以提高程式的執行效能,優化程式的結構。上一個章節我們講了final關鍵字的原理及用法,本章節我們來了解一下static關鍵字原理及其用法。
一. static特點
static是一個修飾符,通常用於修飾變數和方法,如開發過程中用到的字典類資料都會用到static來修飾,工具類方法,如Dateutils,Stringutils這類工具方法也會用到static來修飾,那麼除了這兩種最常用的場景外,是否還有其他場景呢,答案是:有的,總共五種:
- static變數
- static方法
- static程式碼塊
- static內部類
- static包內匯入
static修飾的變數、方法、程式碼塊、內部類在類載入期間就已經完成初始化,儲存在Java Heap(JDK7.0之前儲存在方法區)中靜態儲存區,因此static優於物件而存在。
static修飾的成員(變數、方法)被所有物件所共享,也叫靜態變數或靜態方法,可直接通過類呼叫(也建議通過類呼叫)。
二. static 變數
static變數隨著類的載入而存在,隨著類的消失而消失,當類被載入時,就會為靜態變數在Java Heap中分配記憶體空間,可以通過【類.變數名】和【物件.變數名】的方式呼叫,建議直接使用【類.變數名】的方式,
public class Person {
private String name;
private static int eyeNum;
public static int legNum = 2;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static int getEyeNum() {
return eyeNum;
}
public static void setEyeNum(int eyeNum) {
Person.eyeNum = eyeNum;
}
}
public static void main(String[] args) {
Person person = new Person();
person.setEyeNum(25);
Person person1 = new Person();
person1.setEyeNum(28);
System.out.println(person.getEyeNum());//28
System.out.println(person1.getEyeNum());//28
int legNum = person.legNum;
System.out.println(legNum);//2
}
從上面的例子可以看出靜態變數是對所有物件共享,一個物件對其值的改動,直接就會造成另一個物件取值的不同。
什麼時候使用static變數?
作為共享變數使用,通常搭配final關鍵字一起使用,比如我們常用的字典類資料;
private static final String GENERAL_MAN = "man";
減少物件的建立,比如在類開頭的部分,定義Logger方法,用於異常日誌採集
private static Logger LOGGER = LogFactory.getLoggger(MyClass.class);
始終返回同一變數,比如我們的單例模式。
三. static 方法
靜態方法只能訪問靜態成員(靜態變數、靜態方法),而非靜態方法既可訪問靜態方法也可訪問非靜態方法;因為靜態成員優於物件而存在,因此無法呼叫和物件相關的關鍵字,如this,super,無法通過關鍵字訪問物件資源。
public class Person {
private String name;
private static int eyeNum;
public static int legNum = 2;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static int getEyeNum() {
System.out.println(name);//編譯出錯,name不可用
return eyeNum;
}
public static void setEyeNum(int eyeNum) {
Person.eyeNum = eyeNum;
this.name = "";//編譯出錯,this不可用
}
}
什麼時候使用static方法?
static方法一般用於與當前物件無法的工廠方法、工具方法。如Math.sqrt(),Arrays.sort(),StringUtils.isEmpty()等。
四. static 程式碼塊
static程式碼塊相對於static變數和static方法來說使用不是那麼廣泛,但也算是比較常見的用法了,static程式碼塊在載入一個類的時候最先執行,且只執行一次。
public static Map<String, String> timeTypes;
static {
timeTypes = new HashMap<>();
timeTypes.put("year", "年");
timeTypes.put("quarter", "季");
timeTypes.put("month", "月");
timeTypes.put("day", "日");
System.out.println("初始化1");
}
public static void main(String[] args) {
System.out.println("初始化2");
}
執行結果是:
初始化1;
初始化2;
什麼時候使用static程式碼塊?
一般在進行初始化操作時,比如讀取配置檔案資訊,獲取當前伺服器引數等
五. static內部類
定義一個內部類,加上static,就成為了一個static內部類,static只能修飾內部類,不能修飾頂級類,靜態內部類在業務應用系統開發中使用的不多。
public class StaticCouter {
private String str0 = "hi"; //非靜態變數
private static String str1 = "hello"; //靜態變數
static class StaticInnerClass{//靜態內部類
public void getMessage(){
System.out.println(str0);//編譯出錯
System.out.println(str1);
}
}
class NormalInnerClass{//非靜態內部類
public void getMessage(){
System.out.println(str0);
System.out.println(str1);
}
}
}
靜態內部類與非靜態內部類有何異同?
靜態內部類 | 非靜態內部類 |
---|---|
不需要有指向外部類的引用 | 必須通過外部類的new關鍵字引用 |
可定義普通變數和方法,也可定義靜態變數和方法 | 可定義普通變數和方法,不可定義靜態變數和方法 |
可以呼叫外部類的靜態成員,不能呼叫外部類的普通成員 | 可呼叫外部類的普通成員和靜態成員 |
public static void main(String[] args) {
//建立靜態內部類例項
StaticInnerClass staticInnerClass = new StaticInnerClass();
//呼叫靜態內部類方法
staticInnerClass.getMessage();
//建立靜態內部類例項
StaticCouter.StaticInnerClass staticInnerClass1 = new staticCouter.StaticInnerClass();
//呼叫靜態內部類方法
staticInnerClass1.getMessage();
//建立普通內部類例項
StaticCouter.NormalInnerClass normalInnerClass = new StaticCouter().new NormalInnerClass();
//呼叫普通內部類方法
normalInnerClass.getMessage();
}
六. static包內匯入
這個概念不太好理解,舉個例子
public static void main(String[] args) {
int[] arra = {1,4,5,7};
Arrays.sort(arra);
Arrays.asList(arra);
Arrays.fill(arra, 6);
}
static包匯入目的就是去掉重複的Arrays類名呼叫
通過在頂部引入
import static java.util.Arrays.*
即可把Arrays類中所有的靜態變數,方法,內部類等都引入當前類中,呼叫時直接呼叫sort(arra),asList(arra),
java5後引入的,不常用,呼叫類方法時會比較簡單,但可讀性不好,慎用。
七. 總結
static是java中很常用的一個關鍵字,使用場景也很多,本文主要介紹了它的五種用法,static變數,static方法,static程式碼塊,static內部類,static包內匯入,若有不對之處,請批評指正,望共同進步,謝謝!