使用靜態塊的好處:只要在類被加載時,static塊就會被調用,整個過程就調用這麼一次,不會在後面的對象處又不斷的調用。若是不使用它,就會出現以下問題:new一個對象,我就要調用一次所需的這些內容,重複被調用,從而增長開銷。java
程序1:這個程序就是用靜態方法塊,測試輸入一我的的出生日期,判斷是否在給定出生日期範圍內出生,若是是就返回true,不然返回false。sql
package com.liaojianya.chapter5; import java.sql.Date; /** * This program will demonstrate the use of staticBlock. * @author LIAO JIANYA * */ public class StaticBlock { public static void main(String[] args) { Person1 p = new Person1(Date.valueOf("1998-11-12")); Person1 p1 = new Person1(Date.valueOf("1988-11-12")); System.out.println("Is this p born between 1980 and 1990:" + p.isBornBoomer()); System.out.println("Is this p1 born between 1980 and 1990:" + p1.isBornBoomer()); } } class Person1 { private Date birthDate; private static Date startDate, endDate; static { startDate = Date.valueOf("1980-01-11"); endDate = Date.valueOf("1990-01-11"); } public Person1(Date birthDate) { this.birthDate = birthDate; } boolean isBornBoomer() { return birthDate.compareTo(startDate) >= 0 && birthDate.compareTo(endDate) < 0; } }
結果顯示:測試
Is this p born between 1980 and 1990:false Is this p1 born between 1980 and 1990:true
TIP:先前寫這個程序的時候,遇到的問題就是在Person1 p = new Person1();lthis
這個時候,我嘗試在括號裏賦日期值,報各類錯誤,而後才發現須要用到一個java.lang.sql裏的Date.valueOf("YYYY-MM-DD")格式,而不能直接賦一個數字年份。對象
查了一下API以下:blog
public static Date valueOf(String s)字符串
將 JDBC 日期轉義形式的字符串轉換成 Date 值。string
參數:
s - 表示 "yyyy-mm-dd" 形式的日期的 String 對象
返回:
表示給定日期的 java.sql.Date 對象
拋出:
IllegalArgumentException - 若是給定日期不是 JDBC 日期轉義形式 (yyyy-mm-dd)。it
程序2:io
package com.liaojianya.chapter1; /** * This program demonstrates the use of attribute of class. * @author LIAO JIANYA * 2016年7月20日 */ public class UsingAttribute { static String a = "string-a"; static String b; String c = "string-c"; String d; static { printStatic("before static"); b = "string-b"; printStatic("after static"); } public static void printStatic(String title) { System.out.println("--------" + title + "--------"); System.out.println("a = \"" + a + "\""); System.out.println("b = \"" + b + "\""); } public UsingAttribute() { print("before constructor"); d = "string-d"; print("after constructor"); } public void print(String title) { System.out.println("--------" + title + "--------"); System.out.println("a = \"" + a + "\""); System.out.println("b = \"" + b + "\""); System.out.println("c = \"" + c + "\""); System.out.println("d = \"" + d + "\""); } public static void main(String[] args) { System.out.println(); System.out.println("------------create UsingAttribute object------------"); System.out.println(); new UsingAttribute(); System.out.println("----------------again---------------"); new UsingAttribute(); } }
運行結果:
--------before static-------- a = "string-a" b = "null" --------after static-------- a = "string-a" b = "string-b" ------------create UsingAttribute object------------ --------before constructor-------- a = "string-a" b = "string-b" c = "string-c" d = "null" --------after constructor-------- a = "string-a" b = "string-b" c = "string-c" d = "string-d" ----------------again--------------- --------before constructor-------- a = "string-a" b = "string-b" c = "string-c" d = "null" --------after constructor-------- a = "string-a" b = "string-b" c = "string-c" d = "string-d"
分析:
初始化順序:
類屬性(靜態變量)定義時的初始化,如static String a = "string-a"
static 塊中的初始化代碼,如static{}中的b = 「string-b」
對象屬性(非靜態變量)定義時的初始化, 如String c = 「string-c」
構造方法中的初始化代碼,如d ="string-d"
1)static語句塊用於初始化static成員變量,是最早運行的語句塊,只要在類被加載時,static塊就會被調用,整個過程就調用這麼一次,不會在後面的對象處又不斷的調用。
2)被static修飾的變量稱爲類變量(class‘s variables),被類的實例所共享,某一個類的實例改變了這個靜態值,其餘這個類的實例也會受到影響。而成員變量(member variables)則是沒有被static修飾的變量,爲實例所私有,即每一個類的實例都有一份本身專屬的成員變量,只有當前實例才能夠改變它們的值。