Java Static關鍵字詳解

先思考兩個問題:

1.爲何要使用Static關鍵字?

2.加了Static關鍵字修飾後會有什麼不一樣?  

Static

一.爲何要使用Static關鍵字?編程

這裏摘錄一下《Java編程思想(第四版)》裏關於static關鍵字的一段原話:(P29)一般來講,當建立類時,就是在描述那個類的對象的外觀與行爲。除非用new建立那個對象,不然,實際上並未得到任何對象。執行new來建立對象的時候,數據存儲空間才被分配,其方法才供外界調用。有兩種情形用上述方法是沒法解決的。一種情形是,只想爲某特定域分配單一存儲空間,而不去考慮究竟要建立多少個對象,甚至根本不須要建立任何對象。另外一種情形是,但願某個方法不與包含他的類的任何對象關聯在一塊兒。也就是說,即便沒有建立對象,也可以調用方法。簡單來講,static的主要目的就是建立獨立於具體對象的域變量與方法。jvm

二.加了Static關鍵字修飾會有什麼不一樣?this

1.this不能調用被static修飾的屬性字段。spa

   由於被static修飾的會在類加載的時候初始化,被稱爲類級變量(屬於類);而類的實例是在運行的時候初始化,屬於對象級變量(屬於對象)。指針

   this是指當前對象的實例,super是指父類對象的實例。this(super)不能調用被static修飾的屬性字段的緣由:jvm有類加載器,第一次加載時執行static域,jvm會專門劃分一個內存區域給static程序塊,因此何時均可以調用這個被static修飾的屬性字段或者方法,屬於類。this指針是指向類的對象,在實例化對象時候jvm會在堆區分配給一個具體對象,this指向該對象。因此在靜態方法中不能調用非靜態屬性或者方法,若是在靜態方法中使用this關鍵字,則this沒法指向合適的對象。(通俗一點的話:即jvm的類加載機制決定了加載靜態會先與非靜態,即加載靜態的時候非靜態屬性和方法都不存在)code

 

2.static修飾屬性和方法對象

1.static修飾屬性時候,即全部該類對象共享一份存儲空間。blog

 

public class StaticTest {
    public static int staticA;
    public int A;
    
    public static void main(String[] args){
       StaticTest test;
       StaticTest A1=new StaticTest();
       StaticTest A2=new StaticTest();
       A1.staticA++;
       A2.staticA++;
       A1.A++;
       A2.A++;
       System.out.println("StaticAInfo:"+A1.staticA+" "+A2.staticA);
       System.out.println("AInfo"+A1.A+" "+A2.A);
    }
}

/** 運行結果
 * StaticAInfo:2 2
 * AInfo1 1
 **/

 

即static修飾的不是某個具體對象全部,而是該類全部對象共有的,StaticTest.staticA只有一份存儲空間。內存

2.static修飾方法時候,類和對象都能調用該方法,沒有被static修飾的方法只能被實例化對象調用。資源

public class StaticTest {
    public static void staticTest(){
        
    }    
    public void test(){
        
    }
      
    public static void main(String[] args){
       StaticTest.staticTest();
       //StaticTest.test();  該調用是錯誤的
       StaticTest test=new StaticTest();
       test.staticTest();
       test.test();
    }
}

static修飾成員方法最大的做用,就是可使用"類名.方法名"的方式操做方法,避免了先要new出對象的繁瑣和資源消耗,一個static修飾的類中,不能使用非static修飾的成員變量和方法,這很好理解,由於static修飾的方法是屬於類的,若是去直接使用對象的成員變量,它會不知所措(不知該使用哪個對象的屬性)。

static修飾成員方法的時候最大的好處是能夠節省new一個對象的開銷,便可以直接經過類來調用方法。

3.static修飾內部類

通常用的比較少只能用來修飾內部類,一個static修飾的內部類中,不能使用非static修飾的成員變量和方法,這很好理解,由於static修飾的方法是屬於類的,若是去直接使用對象的成員變量,它會不知所措(不知該使用哪個對象的屬性)。

4.靜態塊

class Book{
    public Book(String msg) {
        System.out.println(msg);
    }
}

public class Person {

    Book book1 = new Book("book1成員變量初始化");
    static Book book2 = new Book("static成員book2成員變量初始化");
    
    public Person(String msg) {
        System.out.println(msg);
    }
    
    Book book3 = new Book("book3成員變量初始化");
    static Book book4 = new Book("static成員book4成員變量初始化");
    
    public static void funStatic() {
        System.out.println("static修飾的funStatic方法");
    }
    
    public static void main(String[] args) {
        Person.funStatic();
        System.out.println("****************");
        Person p1 = new Person("p1初始化");
    }
    /**Output
     * static成員book2成員變量初始化
     * static成員book4成員變量初始化
     * static修飾的funStatic方法
     * ***************
     * book1成員變量初始化
     * book3成員變量初始化
     * p1初始化
     *///~
}

在上面的例子中咱們能夠發現兩個有意思的地方,第一個是當咱們沒有建立對象,而是經過類去調用類方法時,儘管該方法沒有使用到任何的類成員,類成員仍是在方法調用以前就初始化了,這說明,當咱們第一次去使用一個類時,就會觸發該類的成員初始化。第二個是當咱們使用了類方法,完成類的成員的初始化後,再new該類的對象時,static修飾的類成員沒有再次初始化,這說明,static修飾的類成員,在程序運行過程當中,只須要初始化一次便可,不會進行屢次的初始化

 

class Book{
    public Book(String msg) {
        System.out.println(msg);
    }
}

public class Person {

    Book book1 = new Book("book1成員變量初始化");
    static Book book2;
    
    static {
        book2 = new Book("static成員book2成員變量初始化");
        book4 = new Book("static成員book4成員變量初始化");
    }
    
    public Person(String msg) {
        System.out.println(msg);
    }
    
    Book book3 = new Book("book3成員變量初始化");
    static Book book4;
    
    public static void funStatic() {
        System.out.println("static修飾的funStatic方法");
    }
    
    public static void main(String[] args) {
        Person.funStatic();
        System.out.println("****************");
        Person p1 = new Person("p1初始化");
    }
    /**Output
     * static成員book2成員變量初始化
     * static成員book4成員變量初始化
     * static修飾的funStatic方法
     * ***************
     * book1成員變量初始化
     * book3成員變量初始化
     * p1初始化
     *///~
}
相關文章
相關標籤/搜索