java 核心技術(shù)-12版 卷Ⅰ- 4.2.3 更改器方法與訪問器方法
????再來看上一節(jié)中的plusDays方法調(diào)用:
????LocalDate aThousandDaysLater = newYearEve.plusDays(1000);
????這個調(diào)用之后 newYearsEve會有什么變化?它會改為1000天之后的日期嗎?事實(shí)上,并沒有。plusDays方法會生成一個新的LocalDate對象,然后把這個新對象賦給?aThousandDaysLater 變量。原來的對象不會做任何改動。我們說plusDays 方法沒有更改(mutate)調(diào)用這個方法的對象。(這類似于第3章堅果的String類的 toUpperCase方法。在一個字符串上調(diào)用toUpperCase時,這個字符串扔保持不變,并返回一個包含大寫字符的新字符串)
????JAVA庫的一個較早版本曾經(jīng)有另一個處理日歷的類,名為 GreporianCalender??梢匀缦聻檫@個類表示的一個日期增加1000天:
? ? 與LocalDate.plusDays 方法不同,GreporianCalender.add方法是一個更改器方法(mutator method)。調(diào)用這個方法后,someDay對象的狀態(tài)會改變??梢匀缦虏榭葱聽顟B(tài):
?
????正是這個原因,我們將變量命名為someDay而不是 newYearsEve —— 調(diào)用這個更改器方法之后,它不再是新年前夜。
????相反,只訪問對象而不修改對象的方法有時成為訪問器方法(accessor method)。例如,LocalDate.getYear和?GreporianCalender.get就是訪問器方法。
????C++注釋:在C++中,帶有const后綴的方法是訪問器方法;沒有聲明為const的方法默認(rèn)為更改器方法。但是,在Java語言中,訪問器方法與更改器方法在語法上沒有明顯的區(qū)別。
????下面用一個具體應(yīng)用LocalDate 類的程序來結(jié)束這一節(jié)。這個程序?qū)@示當(dāng)前月的日歷,格式如下
????當(dāng)前日期標(biāo)記有一個*號??梢钥吹剑@個程序需要知道如何計算某月份的天數(shù)以及一個給定日期是星期幾。
????下面來看這個程序的關(guān)鍵步驟。首先構(gòu)造一個對象,并用當(dāng)前的日期初始化。
????LocalDate date = LocalDate.now();
????下面獲得當(dāng)前的月份和日期。
????int month= date.getMonthValue();
????int today = date.getDayOfMonth();
????然后,將date設(shè)置為這個月的第一天,并得到這一天為星期幾。
????date = date.minusDays(today -1); // set to start of month 獲得本月1號
????DayofWeek weekDay = date.getDayOfWeek();
????int value = weekday.getValue(); // 1= monday... 7=sunday.? ?1代表星期1,7代表星期日
????變量weekday 設(shè)置為DayOfWeek類型的對象。我們調(diào)用這個對象的getValue方法來得到對應(yīng)星期幾的一個數(shù)值。這會得到一個整數(shù),這里遵循國際慣例,即周末是一周的結(jié)束,星期一就返回1,星期二返回2,以此類推,星期日返回7.
????注意,日歷的第一行是縮進(jìn)的,使當(dāng)月第一天對應(yīng)正確的星期幾。下面的代碼會打印表頭和第一行的縮進(jìn):
????
????現(xiàn)在我們來打印日歷的主體。進(jìn)入一個循環(huán),其中date遍歷一個月的每一天。
????每次迭代中,我們要打印日期止。如果date 是當(dāng)前日期,這個日期則用一個* 標(biāo)記。接下來,把 date 推進(jìn)到下一天。如果到達(dá)新的一周的第一天,則換行打印:
????
????什么時候結(jié)束呢?我們不知道這個月有幾天,是31 天,30天,還是28天?實(shí)際上,只要date 還在當(dāng)月就要繼續(xù)迭代。
????程序清單 4-1 給出了完整的程序。
????可以看到,利用LocalDate 類可以編寫一個日歷程序,它能處理星期幾以及各月天數(shù)不同等復(fù)雜問題。你并不需要知道LocalDate 類如何計算月和星期幾,只需要使用這個類的接口,也就是諸如 plusDays 和 getDayOfWeek等。
????這個示例程序的重點(diǎn)是向你展示如何使用一個類的接口來完成相當(dāng)復(fù)雜的任務(wù),而無須了解實(shí)現(xiàn)細(xì)節(jié)。
????程序清單 4-1 CalenderTest.java
API java.time.LocalDate 8
static LocalDate now() 構(gòu)造一個表示當(dāng)前日期的對象
static LocalDate of(int year,int month, int day) 構(gòu)造一個表示指定日期的對象
int getYear() 獲取當(dāng)前年份
int getMonthValue() 獲取當(dāng)前月份
int getDayOfMonth() 獲取當(dāng)前日期
DayOfWeek getDayOfWeek() 得到當(dāng)前日期是星期幾,作為 DayOfWeek類的一個實(shí)例返回。在DayOfWeek實(shí)例上調(diào)用getValue 來得到 1~7之間的一個數(shù),表示這是星期幾,1表示星期一,2表示星期二,以此類推,7表示星期日
LocalDate plusDays(int n) 生成當(dāng)前日期之后n天的日期
LocalDate minusDays(int n) 生成當(dāng)前日期之前n天的日期