java 核心技术-12版 卷Ⅰ- 4.2.3 更改器方法与访问器方法
再来看上一节中的plusDays方法调用:
LocalDate aThousandDaysLater = newYearEve.plusDays(1000);
这个调用之后 newYearsEve会有什么变化?它会改为1000天之后的日期吗?事实上,并没有。plusDays方法会生成一个新的LocalDate对象,然后把这个新对象赋给 aThousandDaysLater 变量。原来的对象不会做任何改动。我们说plusDays 方法没有更改(mutate)调用这个方法的对象。(这类似于第3章坚果的String类的 toUpperCase方法。在一个字符串上调用toUpperCase时,这个字符串扔保持不变,并返回一个包含大写字符的新字符串)
JAVA库的一个较早版本曾经有另一个处理日历的类,名为 GreporianCalender。可以如下为这个类表示的一个日期增加1000天:
与LocalDate.plusDays 方法不同,GreporianCalender.add方法是一个更改器方法(mutator method)。调用这个方法后,someDay对象的状态会改变。可以如下查看新状态:
正是这个原因,我们将变量命名为someDay而不是 newYearsEve —— 调用这个更改器方法之后,它不再是新年前夜。
相反,只访问对象而不修改对象的方法有时成为访问器方法(accessor method)。例如,LocalDate.getYear和 GreporianCalender.get就是访问器方法。
C++注释:在C++中,带有const后缀的方法是访问器方法;没有声明为const的方法默认为更改器方法。但是,在Java语言中,访问器方法与更改器方法在语法上没有明显的区别。
下面用一个具体应用LocalDate 类的程序来结束这一节。这个程序将显示当前月的日历,格式如下
当前日期标记有一个*号。可以看到,这个程序需要知道如何计算某月份的天数以及一个给定日期是星期几。
下面来看这个程序的关键步骤。首先构造一个对象,并用当前的日期初始化。
LocalDate date = LocalDate.now();
下面获得当前的月份和日期。
int month= date.getMonthValue();
int today = date.getDayOfMonth();
然后,将date设置为这个月的第一天,并得到这一天为星期几。
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 设置为DayOfWeek类型的对象。我们调用这个对象的getValue方法来得到对应星期几的一个数值。这会得到一个整数,这里遵循国际惯例,即周末是一周的结束,星期一就返回1,星期二返回2,以此类推,星期日返回7.
注意,日历的第一行是缩进的,使当月第一天对应正确的星期几。下面的代码会打印表头和第一行的缩进:
现在我们来打印日历的主体。进入一个循环,其中date遍历一个月的每一天。
每次迭代中,我们要打印日期止。如果date 是当前日期,这个日期则用一个* 标记。接下来,把 date 推进到下一天。如果到达新的一周的第一天,则换行打印:
什么时候结束呢?我们不知道这个月有几天,是31 天,30天,还是28天?实际上,只要date 还在当月就要继续迭代。
程序清单 4-1 给出了完整的程序。
可以看到,利用LocalDate 类可以编写一个日历程序,它能处理星期几以及各月天数不同等复杂问题。你并不需要知道LocalDate 类如何计算月和星期几,只需要使用这个类的接口,也就是诸如 plusDays 和 getDayOfWeek等。
这个示例程序的重点是向你展示如何使用一个类的接口来完成相当复杂的任务,而无须了解实现细节。
程序清单 4-1 CalenderTest.java
API java.time.LocalDate 8
static LocalDate now() 构造一个表示当前日期的对象
static LocalDate of(int year,int month, int day) 构造一个表示指定日期的对象
int getYear() 获取当前年份
int getMonthValue() 获取当前月份
int getDayOfMonth() 获取当前日期
DayOfWeek getDayOfWeek() 得到当前日期是星期几,作为 DayOfWeek类的一个实例返回。在DayOfWeek实例上调用getValue 来得到 1~7之间的一个数,表示这是星期几,1表示星期一,2表示星期二,以此类推,7表示星期日
LocalDate plusDays(int n) 生成当前日期之后n天的日期
LocalDate minusDays(int n) 生成当前日期之前n天的日期