JAVA面試題 淺析Java中的static關鍵字

面試官Q1:請說說static關鍵字,你在項目中是怎麼使用的?java

  • static 關鍵字能夠用來修飾:屬性、方法、內部類、代碼塊;面試

  • static 修飾的資源屬於類級別,是全體對象實例共享的資源;線程

  • 使用 static 修飾的屬性,靜態屬性是在類的加載期間初始化的,使用類名.屬性訪問對象

案例說明blog

①修飾成員變量內存

 package com.ant.param;
 public class StaticFieldDemo {
     public static void main(String[] args) {
         Foo f1 = new Foo();
         Foo f2 = new Foo();
         Foo f3 = new Foo();
         System.out.println(f1.id + " " + f2.id + " " + f3.id );
     }
 }
class Foo{
    int id;
}
運行結果以下:
0 0 0

上面的代碼咱們很熟悉,根據Foo構造出的每個對象都是獨立存在的,保存有本身獨立的成員變量,相互不會影響,他們在內存中的示意以下:資源

從上圖中能夠看出,f一、f2和f3三個變量引用的對象分別存儲在內存中堆區域的不一樣地址中,因此他們之間相互不會干擾。對象的成員屬性都在這了,由每一個對象本身保存。f1.id、f2.id、f3.id至關於「每一個人一個水杯」。class

咱們對上面的代碼,作以下修改:變量

package com.ant.param;
 public class StaticFieldDemo {
     public static void main(String[] args) {
         Foo f1 = new Foo();
         Foo f2 = new Foo();
         Foo f3 = new Foo();
         System.out.println(f1.id + " " + f2.id + " " +
         f3.id + " " + Foo.i);
     }
}
class Foo{
    int id;
    static int i=0;
    public Foo(){
        id = i++;
    }
}
運行結果以下:
0 1 2 3

程序執行過程內存圖以下所示:配置

第 1 步:加載類

static修飾的變量在類加載期間初始化,且在方法區中分配,屬於線程共享區,全部的對象實例共享一份數據。

第 2步:繼續加載類

第 3步:繼續加載類

 

最終加載結果如上述三個步驟

 

②修飾成員方法

static的另外一個做用,就是修飾成員方法。相比於修飾成員屬性,修飾成員方法對於數據的存儲上面並無多大的變化,由於咱們從上面能夠看出,方法原本就是存放在類的定義當中的(方法區)。static修飾成員方法最大的做用,就是可使用"類名.方法名"的方式操做方法,避免了先要new出對象的繁瑣和資源消耗,咱們可能會常常在幫助類中看到它的使用:

 package com.ant.param;
 
 public class StaticFieldDemo {
     private static void print(){
         System.out.println("hello");
     }
     public static void main(String[] args) {
         StaticFieldDemo.print();
     }
}

③修飾靜態代碼塊

靜態代碼塊是在類加載期間運行的代碼塊,因爲類只加載一次,因此靜態代碼塊只執行一次!靜態代碼塊用途很常見,通常用來在類加載之後初始化一些靜態資源時候使用。如:加載配置文件等

package com.ant.param;
 
 public class StaticBlockDemo {
     public static void main(String[] args) {
         Foo foo = new Foo();
     }
 }
 
 class Foo{
    //代碼塊,在建立對象的時候執行,使用不多,和構造器差很少
    {
        System.out.println("建立對象了!");
    }
    //靜態代碼塊,在類加載期間執行,用於加載配置文件或者其餘信息等
    static{
        System.out.println("類加載了!");
    }
    public Foo(){
        System.out.println("調用了構造器!");
    }
}

靜態塊用法:將多個類成員放在一塊兒初始化,使得程序更加規整,對理解對象的初始化過程很是關鍵;

在個人印象中,這些問題通常初中級Java工程師會被問到,都是很常規的面試題,您會了嗎?

相關文章
相關標籤/搜索