Java static的用法以及原理(06)


靜態:static

用法:是一個修飾符,用於修飾成員(成員變量,成員函數),

  當成員被靜態修飾后,就多了一個調用方式,除了可以被對象調用外,還可以直接被類名調:類名.靜態成員

    類名.靜態成員

存在:方法區,共享區,數據區(非堆內存、棧內存的另一個存儲區),Static 塊僅在該類被加載時執行一次。

 

static特點:

1,隨着類的加載而加載,也就是說靜態會隨着類的消失而消失,說明他的生命周期最長

2,優先於對象的存在。(靜態先存在,對象后存在。)

3,被所有對象所共享

4,可以直接被類名調用

  由於靜態static不依賴於任何對象就可以進行訪問,因此對於靜態來說,是沒有this的,因為它不依附於任何對象,既然都沒有對象,就談不上this了。並且由於這個特性,在靜態方法中不能訪問類的非靜態成員變量和非靜態成員方法,因為非靜態成員方法/變量都是必須依賴具體的對象才能夠被調用。

  內部類中不能存在static修飾的成員,因為static隨着類加載產生,內部類依附於宿主類,系統加載:宿主類-->靜態-->內部類,而內部類的靜態是隨着內部類加載產生,與加載類就加載static矛盾,所以內部類中不能存在static修飾

實例變量和類變量的區別:
1,存放位置。
  類變量隨着類的加載而存在於方法區中。
  實例變量隨着對象的建立而存在於堆內存中。
2,生命周期:
  類變量生命周期最長,隨着類的消失而消失。
  實例變量生命周期隨着對象的消失而消失。

靜態使用注意事項:

1,靜態方法只能訪問靜態成員,非靜態方法既可以訪問靜態也可以訪問非靜態。(Java虛擬機(JVM)加載類時,就會執行該static,靜態優先於其他產生對象產生)。

2,靜態方法中不可定義this,super等關鍵字:

    (this:this代表當前對象,static於類加載的時候存在優先於實例對象的產生,static調用非靜態時並未產生對象,所以this不代表任何對象為null,未進行初始化操作。)

3,主函數是靜態方法。 

靜態有利有弊:

利:對對象的共享數據進行單獨空間的存儲,節省空間,沒有必要每一格對象中都存儲一份。可以直接被類名調用。

弊:生命周期過長,訪問出現局限性(靜態雖好,只能訪問靜態) 

 

static和final一塊用表示什么 
1,static final用來修飾成員變量和成員方法,可簡單理解為"全局常量"
2,對於變量,表示一旦給值就不可修改,並且通過類名可以訪問。 
3,對於方法,表示不可覆蓋,並且可以通過類名直接訪問。

類成員變量:

static修飾:靜態變量或類變量

無static修飾:實例變量

  靜態變量在內存中只有一個拷貝(節省內存),JVM只為靜態分配一次內存(方法區,共享區,數據區),在加載類的過程中完成靜態變量的內存分配,可用類名.成員,當然也可以通過對象來訪問(但是這是不推薦的,對象產生新的開辟內存空間,static優先於對象的產生,節省內存)。 

  不能直接訪問所屬類的實例變量和實例方法

  static方法獨立於任何實例,因此static方法必須被實現,而不能是抽象的abstract。

什么時候使用靜態:

  因為靜態修飾的內容有成員變量和函數。

  使用靜態變量(類變量):當對象中出現共享數據時,該數據被靜態所修飾。對象中的特有數據要定義成非靜態存在於堆內存中。

  使用靜態函數:當功能內部沒有訪問到非靜態數據(對象的特有數據),那么該功能可以定義成靜態的

靜態代碼塊。
  格式:
    static{
        靜態代碼塊中的執行語句。
      }

  特點:隨着類的加載而執行,只執行一次,並優先於主函數。用於給類進行初始化的。

class StaticCode
  {
	int num = 9;
	StaticCode()
	{
		System.out.println("b");
	}

	static
	{
            //只執行一次,並優先於主函數。
    
		System.out.println("a");
	}
	{
		System.out.println("c"+this.num);
	}

	StaticCode(int x)
	{
		System.out.println("d");
	}
	public static void show()
	{
		System.out.println("show run");
	}
}

class StaticCodeDemo 
  {
	static
	{
		System.out.println("b");//(1)
	}
	public static void main(String[] args) 
	{
	
            //盡管new StaticCode兩次,但是靜態代碼塊只執行一次
	 (1)new StaticCode();
		 new StaticCode();
		 System.out.println("over");   //b c a over     
                //構造代碼塊優先於對象產生
                //優先級:靜態代碼庫>代碼塊>對象產生
	  (2)new StaticCode(4);//b c a c9 d 
		//StaticCode.show();//b c a  show run c9 
            (3)當構造代碼對象為空時,沒有任何意義,未使用該類,所以哪怕是靜態成員也不存在
		//StaticCode s = null;
           (4)
		//s = new StaticCode();//b c a  c9 b


	}
	static
	{
		System.out.println("c");//(2)
	}
}
//d:\>java0217\day06>java StaticCodeDemo 先加載b c
                         

  


  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM