1. 程式人生 > 實用技巧 >【Azure 儲存服務】Python模組(azure.cosmosdb.table)直接對錶儲存(Storage Account Table)做操作示例

【Azure 儲存服務】Python模組(azure.cosmosdb.table)直接對錶儲存(Storage Account Table)做操作示例

技術標籤:static初學JAVAjava

JAVA 程式碼由類組成,而類由屬性 (即變數)和方法組成,沒任何方法和屬效能夠在類外面;而屬性和方法又分為靜態或非靜態,靜態與非靜態的生存期、級別、生成順序都是有區別的;所謂靜態就是以 static 所修飾的屬性或方法;

特點:

  • 與方法中的區域性變數不一樣,由 static 所修飾的成員的生存期和類是相同的;

    這一點很好驗證:
public class test
{
	public static void main (String[] args)
	{
		System.out.println (book.name);
	}
}
class
book { static String name = "JAVA program"; }

在這裡插入圖片描述
之前我們說過要引用不同類中的引用資料型別需要用 new 開闢一塊記憶體空間之後才能引用,但這裡我們沒有用 new 而是直接引用,因為加了 static 關鍵字之後成員屬性 String name 與方法同時產生,當還沒有執行主方法的時候就已經存在了,因此並不需要再用 new 來開闢空間;
假如我們把關鍵字 static 去掉就會出問題:

public class test
{
	public static void main (String[] args)
	{
		System.
out.println (book.name); } } class book { String name = "JAVA program"; }

在這裡插入圖片描述
可以看到系統報錯說無法引用費靜態變數book.name,因為當主方法壓棧之後並未對引用資料型別 book 開闢記憶體空間,系統無法找到相應的地址,當我們用了 new 之後又可以了:

public class test
{		
	public static void main (String[] args)
	{
		book one = new book ();
		System.out.println (one.name)
; } } class book { String name = "JAVA program"; }

在這裡插入圖片描述
這裡需要注意,如果說把 book one = new book ();放在了主方法的外面則又會出現剛才一樣的報錯;
我們都知道 JAVA 是順序向下執行的,並且內部的 GC 機制會自動幫我們回收沒有用到的垃圾,當 test.class 檔案載入到方法區後在 main 方法壓棧之前就直接通過 new 生成了引用資料型別,然而當 book one = new book ();執行完畢後並未對其進行操作也沒有用 static 關鍵字進行保留,因此 GC 為了保留記憶體將其判定為垃圾自動回收,之後 main 方法壓棧,這時 one 已經被回收了,相當於沒有,所以還是找不到;

  • 靜態方法只能訪問靜態成員變數,無法訪問非靜態成員變數,但可以通過建立類來訪問非靜態成員變數;

    這一點其實在上面已經驗證過了,無論是訪問同一個類中的成員變還是訪問不同類中的成員變數,在未加 static 關鍵字的時候 main 方法 (main 方法是 static 修飾的) 都不可訪問,而通過在方法中用建立類來呼叫就可以訪問;
  • 靜態方法可以呼叫靜態方法,無法呼叫非靜態方法,但可以通過建立類來呼叫非靜態方法;

public class test
{
	public static void main (String[] args)
	{
		hello ();
	}
	public static void hello ()
	{
		System.out.print ("hello");
		world ();
	}
	public static void world ()
	{
		System.out.println (" world");
	}
}

在這裡插入圖片描述
這時候是可以正常執行的,但當我們把 world 中的 static 關鍵字去掉之後:

public class test
{
	public static void main (String[] args)
	{
		hello ();
	}
	public static void hello ()
	{
		System.out.print ("hello");
		world ();
	}
	public void world ()
	{
		System.out.println (" world");
	}
}

在這裡插入圖片描述
我們可以看到在編譯是報了跟之前一樣的錯誤;

我們知道 JVM 中的方法區存放所有以 static 修飾的成員,以 static 所修飾的變數或者方法與 .class 檔案同時載入到方法區中,可以說他們是同時出生的,形象的可以看作類多少歲,以 static 所修飾的變數或者方法就多少歲,他們是同級的;而沒有被 static 所修飾的方法並不會與 .class 檔案一起載入到方法區中,當呼叫它的時候需要通過引用資料型別用 new 來開闢一塊空間來得到一個首地址,再由首地址找到該方法的地址,再進行呼叫;如此看來非靜態方法的使用過程其實和成員屬性的使用過程是一模一樣的,因此可以得出結論非靜態方法其實是屬於物件級別的;

既然如此就很好解釋了,類級別的是最先產生的,而物件級別的則需要在靜態方法壓棧後在棧中進行應用才產生,那麼當沒有引用時物件級別的就不存在,因此在靜態方法中直接呼叫非靜態方法是不可以的;就好比你滿世界的去找一個還沒有出生的人,怎麼可能找得到呢?

對於上面這個程式碼,當在 hello 方法中呼叫 world 方法時並未對 test 類開闢空間,因此無法得知 world 方法的地址,我們像前面一樣做:

public class test
{
	public static void main (String[] args)
	{
		hello ();
	}
	public static void hello ()
	{
		test wor = new test ();
		System.out.print ("hello");
		wor.world ();
	}
	public void world ()
	{
		System.out.println (" world");
	}
}

在這裡插入圖片描述
這裡又可以了,說明以上推斷是沒有問題的;

這裡引申出一個新的東西,叫做靜態程式碼塊;

  • static 程式碼塊:

所謂靜態程式碼塊就是以 static { } 的形式編寫的程式碼塊, static 程式碼塊中的執行語句無需呼叫直接就可以執行,同時與用 static 修飾的成員一樣與類是同一級別的,但不一樣的是,它只能在類初始化的時候執行一次,執行完畢就銷燬,並且優先於 main 方法執行。從這裡我們可以推斷它是在方法區執行;

通過一個簡單的程式碼來驗證一下:

public class test
{
	public static void main (String[] args)
	{
		System.out.println ("SiChuan");
	}
	static
	{
		System.out.println ("China");
	}
}

在這裡插入圖片描述
從結果可以看到確實是優先於 main 方法執行的;

但我們知道 main 方法是整個程式的入口,除了類體中定義的成員屬性之外,它一定是第一個壓棧的,但 static 程式碼塊卻優先於 main 方法,要滿足以上條件就只能是 static 程式碼塊是在方法區執行;

方法區的記憶體比棧區要大我們可以通過 static 程式碼塊在方法區直接完成一些操作來提高程式的執行效率,一般用於初始化,但也不限於初始化。

  • 例項程式碼塊:

    例項程式碼塊就是直接用 { } 所編寫的程式碼塊,它優先於 main 方法,但落後於 static 方法被執行,可以執行多次,在構造方法執行之前自動執行一次;

    同樣我們來驗證一下:

public class test
{
	public test ()
	{
		System.out.println ("ChengDu");
	}
	public static void main (String[] args)
	{
		new test ();
		new test ();
	}
	static
	{
		System.out.println ("China");
	}
	{
		System.out.println ("SiChuan");
	}
}

在這裡插入圖片描述

  • 總結:

    1、static 所修飾的變數或者方法與類是同一級別的;
    2、訪問 static 所修飾的變數無需用類建立物件,可以直接用類名 . 變數名來訪問;
    3、靜態方法不可直接訪問非靜態變數,但可以通過建立物件來訪問;
    4、靜態方法不可直接呼叫非靜態方法,也可以通過建立物件來呼叫;
    5、靜態變數或方法可以直接被呼叫或訪問;
    6、static 程式碼塊優先於 main 方法被執行,且只執行一次;
    7、例項程式碼塊優先於 main 方法,但落後於 static 程式碼塊被執行,且在構造方法執行之前自動指定一次;

以上全屬 JAVA 小白的自我感悟,如有錯誤,還望糾正!!!