前面討論的this關(guān)鍵字,典型地反映了隨著對(duì)象引用的不同,其變量和操作亦不同,體現(xiàn)了面向?qū)ο缶幊痰膬?nèi)涵。但是,有時(shí)在程序中的要求正好與此相反——需要代表整個(gè)類的數(shù)據(jù)。Java提供的靜態(tài)數(shù)據(jù)(static data)就是專門用來實(shí)現(xiàn)這一要求的。
二、類數(shù)據(jù)
靜態(tài)數(shù)據(jù)屬于全體對(duì)象,是所有對(duì)象共享的數(shù)據(jù),或類數(shù)據(jù)。靜態(tài)常量也稱為類常量;靜態(tài)變量也稱類變量。在解決實(shí)際問題中經(jīng)常會(huì)遇到類數(shù)據(jù)。例如,Math.PI,Math.E對(duì)所有對(duì)象的算術(shù)運(yùn)算都是一樣的,它們被定義為Math類的靜態(tài)常量。
再例如,稅收比率在計(jì)算稅款時(shí)對(duì)所有定義的對(duì)象都適用,也是靜態(tài)數(shù)據(jù)的典型例子。有時(shí),我們需要統(tǒng)計(jì)創(chuàng)建了多少個(gè)對(duì)象,或者有多少個(gè)對(duì)象調(diào)用了某個(gè)方法,或者應(yīng)用了某個(gè)操作等等,這需要在程序中使用靜態(tài)數(shù)據(jù)來完成這些任務(wù)。類數(shù)據(jù)可以是private或public。
如下是定義靜態(tài)數(shù)據(jù)的典型例子。
例1.定義靜態(tài)變量。
private static double accountLimit; //定義一個(gè)雙精度靜態(tài)變量
private static int userCount = 0; //定義一個(gè)整數(shù)靜態(tài)變量并賦值
public static String welcome = "Java is hot!"; //定義一個(gè)字符串靜態(tài)變量并賦值
例2.定義靜態(tài)常量。
private static final float TAX_RATE = 0.0875f; //定義一個(gè)浮點(diǎn)靜態(tài)常量
public static final double EARTH_MASS = 5.972e24; //定義一個(gè)雙精度靜態(tài)常量
public static final int MONTH_IN_YEAR = 12; //定義一個(gè)整數(shù)靜態(tài)常量
注意 靜態(tài)常量必須在定義時(shí)賦值。否則為非法。
如下是使用靜態(tài)數(shù)據(jù)的典型例子:
public FutureValue() { //構(gòu)造器
//對(duì)對(duì)象數(shù)據(jù)初始化的各語句
...
userCount++; //每創(chuàng)建一個(gè)對(duì)象,都對(duì)原來統(tǒng)計(jì)用戶數(shù)目的靜態(tài)變量userCount加1
}
public FutureValue(String name) {
this.name = name;
//對(duì)其他各變量初始化的語句
...
userCount++; //同上
}
以上例子表示無論以哪個(gè)構(gòu)造器創(chuàng)建對(duì)象,對(duì)靜態(tài)變量userCount都執(zhí)行加1,達(dá)到統(tǒng)計(jì)對(duì)象的目的。如果執(zhí)行下列輸出語句:
System.out.println(myFutureValue.getUserCount()); //用對(duì)象調(diào)用
其輸出值與:
System.out.pritnln(FutureValue.getUserCount()); //用靜態(tài)方法通過類直接調(diào)用
完全一樣。
靜態(tài)數(shù)據(jù)通常由靜態(tài)方法來調(diào)用。
三、 屬于所有對(duì)象
靜態(tài)數(shù)據(jù)為什么屬于整個(gè)類,或類中的所有對(duì)象呢?這是因?yàn)樗鼈儽粌?chǔ)存在特殊指定的存儲(chǔ)器中。進(jìn)一步講,靜態(tài)數(shù)據(jù)儲(chǔ)存在類訪問區(qū)的儲(chǔ)存空間。這個(gè)儲(chǔ)存空間是這個(gè)類代表的所有對(duì)象共享的,它的訪問生命期和這個(gè)類相同。
而實(shí)例數(shù)據(jù)分別儲(chǔ)存在代表每個(gè)對(duì)象的一段存儲(chǔ)區(qū)域中。假設(shè)我們創(chuàng)建了100個(gè)對(duì)象,那么將有100個(gè)這樣的儲(chǔ)存區(qū)域存在。即每個(gè)對(duì)象都有它自己獨(dú)立存儲(chǔ)區(qū)域,用來存儲(chǔ)它所具有的所有實(shí)例數(shù)據(jù)。這個(gè)存儲(chǔ)區(qū)域的訪問生命期和對(duì)象相同。
四、靜態(tài)數(shù)據(jù)原則
靜態(tài)數(shù)據(jù)是類的組成部分,確定靜態(tài)數(shù)據(jù)首先從類的設(shè)計(jì)入手,分析和確定類的應(yīng)用范疇,它所執(zhí)行的運(yùn)算和操作,包括確定數(shù)學(xué)公式以及運(yùn)算邏輯等。由此來確定靜態(tài)數(shù)據(jù)和實(shí)例數(shù)據(jù)。靜態(tài)數(shù)據(jù)與實(shí)例數(shù)據(jù)本質(zhì)的不同在于:
(1) 實(shí)例數(shù)據(jù)是在這個(gè)類的應(yīng)用中,每個(gè)對(duì)象,或大多數(shù)對(duì)象都具有的、但各自有不同值的數(shù)據(jù)。例如,在計(jì)算投資回報(bào)的程序中,每個(gè)對(duì)象都有姓名(name)、月投資額(monthlyInvest),年投資回報(bào)率(yearlyRate),以及投資年(years),但這些數(shù)據(jù)的值對(duì)每個(gè)對(duì)象來說,是完全由對(duì)象來確定的,與整個(gè)類無關(guān);與具體對(duì)象的形態(tài)有關(guān)。
(2) 靜態(tài)數(shù)據(jù)是所有對(duì)象共享的數(shù)據(jù)。在這個(gè)類的應(yīng)用中,無論哪一個(gè)對(duì)象,如果應(yīng)用這個(gè)數(shù)據(jù)的話,都必須具有相同的值,或者這個(gè)數(shù)據(jù)對(duì)所有對(duì)象都有意義,或者這個(gè)數(shù)據(jù)代表了所有對(duì)象的形態(tài)表征,與整個(gè)類有關(guān)。
根據(jù)以上分析,確定靜態(tài)數(shù)據(jù)可根據(jù)如下原則:
1. 對(duì)類中的對(duì)象進(jìn)行統(tǒng)計(jì)的數(shù)據(jù)應(yīng)該確定為靜態(tài)數(shù)據(jù)。
2. 對(duì)類中所有對(duì)象,設(shè)置上下限的數(shù)據(jù),應(yīng)該確定為靜態(tài)常量數(shù)據(jù)。
3. 在執(zhí)行運(yùn)算的公式和解決問題的邏輯中,某個(gè)常量對(duì)類中所有的對(duì)象,如果有相同應(yīng)用,這個(gè)常量應(yīng)該確定為靜態(tài)常量數(shù)據(jù)。
4. 用來對(duì)類中所有對(duì)象進(jìn)行提示、詢問、問候以及其他與具體對(duì)象無關(guān)的信息或數(shù)據(jù),應(yīng)該確定為靜態(tài)常量數(shù)據(jù)。