Java基礎(六) static五大應用場景

static和final是兩個咱們必須掌握的關鍵字。不一樣於其餘關鍵字,他們都有多種用法,並且在必定環境下使用,能夠提升程序的運行性能,優化程序的結構。上一個章節咱們講了final關鍵字的原理及用法,本章節咱們來了解一下static關鍵字原理及其用法。html

一. static特色

static是一個修飾符,一般用於修飾變量和方法,如開發過程當中用到的字典類數據都會用到static來修飾,工具類方法,如Dateutils,Stringutils這類工具方法也會用到static來修飾,那麼除了這兩種最經常使用的場景外,是否還有其餘場景呢,答案是:有的,總共五種:java

  1. static變量
  2. static方法
  3. static代碼塊
  4. static內部類
  5. 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變量?this

做爲共享變量使用,一般搭配final關鍵字一塊兒使用,好比咱們經常使用的字典類數據;日誌

private static final String GENERAL_MAN = "man";code

減小對象的建立,好比在類開頭的部分,定義Logger方法,用於異常日誌採集orm

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包內導入,如有不對之處,請批評指正,望共同進步,謝謝!

相關文章
相關標籤/搜索