使用靜態塊的好處:只要在類被加載時,static塊就會被調用,整個過程就調用這么一次,不會在后面的對象處又不斷的調用。如果不使用它,就會出現如下問題:new一個對象,我就要調用一次所需的這些內容,重復被調用,從而增加開銷。
程序1:這個程序就是用靜態方法塊,測試輸入一個人的出生日期,判斷是否在給定出生日期范圍內出生,如果是就返回true,否則返回false。
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();l
這個時候,我嘗試在括號里賦日期值,報各種錯誤,然后才發現需要用到一個java.lang.sql里的Date.valueOf("YYYY-MM-DD")格式,而不能直接賦一個數字年份。
查了一下API如下:
public static Date valueOf(String s)
將 JDBC 日期轉義形式的字符串轉換成 Date 值。
參數:
s - 表示 "yyyy-mm-dd" 形式的日期的 String 對象
返回:
表示給定日期的 java.sql.Date 對象
拋出:
IllegalArgumentException - 如果給定日期不是 JDBC 日期轉義形式 (yyyy-mm-dd)。
程序2:
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修飾的變量,為實例所私有,即每個類的實例都有一份自己專屬的成員變量,只有當前實例才可以改變它們的值。
