百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Java核心技术GregorianCalendar类+更改器方法与访问器方法

toyiye 2024-05-19 19:35 20 浏览 0 评论

使用现有类

在Java中,没有类就无法做任何事情。前面曾经接触过几个类,但可惜的是,其中许多并不具有Java类的典型特征。例如,Math类。在程序中,可以使用Math类的方法,如Math.random,并只需要知道方法名和参数(如果有的话),而不必了解它的具体实现过程。这正是封装的关键所在,当然所有类都是这样。但遗憾的是,Math类只封装了功能,它不需要也不必隐藏数据。由于没有数据,因此也不必担心生成对象以及初始化实例域。

在下一节中,将会给出一个更加具有代表性的类—Date类。从中可以看到如何构造对象,以及如何调用类的方法。

对象与对象变量

要想使用对象,就必须首先构造对象,并指定其初始状态。然后,对对象施加方法。

在Java程序设计语言中,使用构造器(constructor)构造新实例。构造器是一种特殊的方法,用来构造并初始化对象。下面看一个例子。在标准Java类库中包含一个Date类。它的对象将描述一个时间点,例如“December 31, 1999, 23:59:59 GMT”。

构造器的名字应该与类名相同。因此Date类的构造器名为Date。要想构造一个Date对象,需要在构造器前面加上new操作符,如下所示:

new Date( )

这个表达式构造了一个新对象。这个对象被初始化为当前的日期和时间。

如果需要的话,也可以将这个对象传递给一个方法:

System.out.println(new Date( ));

相反,也可以将一个方法应用于刚刚构造的对象上。Date类中有一个toString方法。这个方法将返回日期的字符串描述。下面的语句可以说明如何将toString方法应用于新构造的Date对象上。

String s = new Date( ).toString( );

在这两个例子中,构造的对象仅使用了一次。通常,希望构造的对象可以被多次使用,因此,需要将对象存放在一个变量中:

Date birthday = new Date( );

图4-3展示了引用新构造的对象的对象变量birthday。


在对象与对象变量之间存在着一个重要的区别。例如,语句

Date deadline; // deadline doesn’t refer to any object

定义了一个对象变量deadline,它可以引用Date类型的对象。但是,一定要认识到:变量deadline不是一个对象,实际上也没有引用对象。此时,不能将任何Date方法应用于这个变量上。语句

s = deadline.toString( ); // not yet

将产生编译错误。

必须首先初始化变量deadline。这里有两个选择。当然可以用新构造的对象初始化这个变量:

deadline = new Date( );

或者让这个变量引用一个已存在的对象:

deadline = birthday;

现在,这两个变量引用同一个对象(请参见图4-4)。

一定要认识到:一个对象变量并没有实际包含一个对象,而仅仅引用一个对象。

在Java中,任何对象变量的值都是对存储在另外一处的一个对象的引用。new操作符的返回值也是一个引用。下列语句:

Date deadline = new Date( );

有两个部分。表达式new Date( )构造了一个Date类型的对象,并且它的值是对新创建对象的引用。

这个引用被存储在变量deadline中。

可以显式地将对象变量设置为空(null),表明这个对象变量目前没有引用任何对象。

deadline = null;
. . .
if (deadline != null)
System.out.println(deadline);

如果将一个方法应用于一个值为null的对象上,就会产生运行错误。

birthday = null;
String s = birthday.toString( ); // runtime error!

变量不会自动地初始化为null,而必须对它们进行初始化,调用new或将它们设置为null。

Java库中的GregorianCalendar类

在前面的例子中,已经使用了Java标准类库中的Date类。Date类的实例有一个状态,称为特定的时间点。

尽管在使用Date类时不必知道这一点,但时间是用距离一个固定时间点的毫秒数(可正可负)表示的,这个点就是所谓的纪元(epoch),它是UTC时间1970年1月1日00:00:00。UTC是Coordinated Universal Time的缩写,与大家熟悉的GMT(即Greenwich Mean Time/格林威治时间)一样,是一种具有实际目的的科学标准时间。

但是,事实上Date类对于日期的处理并没有太大的用途。Java类库的设计者认为:像“December 31, 1999, 23:59:59”这样的日期表示法只是阳历的固有习惯。这种特定的描述法遵循了世界上大多数地区使用的Gregorian阳历表示法。但是,同一时间若采用中国的农历,或者希伯来的阴历表示就大不一样,对于火星历来说就更不可想象了。

类库设计者决定将保存时间与给时间点命名分开。所以标准Java类库分别包含了两个类:一个是用来表示时间点的Date类;另一个是用来表示大家熟悉的日历表示法的GregorianCalendar类。

事实上,GregorianCalendar类扩展了一个更加通用的Calendar类,这个类描述了日历的一般属性。

理论上,可以通过扩展Calendar类来实现中国的阴历或者是火星日历。然而,标准类库中只实现了Gregorian日历。

将时间与日历分开是一种很好的面向对象设计。通常,最好使用不同的类表示不同的概念。

Date类只提供了少量的方法用来比较两个时间点。例如before和after方法分别返回一个时间点是否早于另一个时间点,或者晚于另一个时间点。

if (today.before(birthday))

System.out.println("Still time to shop for a gift.");

GregorianCalendar类所包含的方法要比Date类多很多。特别是有几个很有用的构造器。表达式

new GregorianCalendar( )

构造一个新对象,用于表示对象构造时的日期和时间。

另外,还可以通过提供年、月、日来构造一个表示某个特定日期午夜的日历对象:

new GregorianCalendar(1999, 11, 31)

有些怪异的是,月份从0开始计数。因此11表示12月。为了清晰起见,也可以使用常量,如:

Calendar.DECEMBER。

new GregorianCalendar(1999, Calendar.DECEMBER, 31)

还可以设置时间:

new GregorianCalendar(1999, Calendar.DECEMBER, 31, 23, 59, 59)

当然,常常希望将构造的对象存储于对象变量中。

GregorianCalendar deadline = new GregorianCalendar(. . .);

GregorianCalendar类封装了实例域,这些实例域保存着设置的日期信息。不查看源代码不可能知道日期在类中的具体表达方式。当然,这一点并不重要,重要的是要知道类向外界开放的方法。

更改器方法与访问器方法

现在,可能有人会问:如何从封装在某个特定的GregorianCalendar对象内部的日期中获得当前的日、月、年呢?如果希望对这些内容做一些修改,又该怎么做呢?在联机文档或本节末尾的API注释中可以找到答案。这里只讲解本节主题中最重要的方法。

日历的作用在于提供某个时间点的日、星期、月或年等属性。要想查询这些设置信息之一,应该使用GregorianCalendar类的get方法。为了表达希望得到的项,需要借助于Calendar类中定义的一些常量,如Calendar.MONTH或Calendar.DAY_OF_WEEK:

GregorianCalendar now = new GregorianCalendar( );
int month = now.get(Calendar.MONTH);
int weekday = now.get(Calendar.DAY_OF_WEEK);

API注释列出了可以使用的全部常量。

调用set方法,可以改变对象的状态:

deadline.set(Calendar.YEAR, 2001);
deadline.set(Calendar.MONTH, Calendar.APRIL);
deadline.set(Calendar.DAY_OF_MONTH, 15);

另外,还有一种便于设置年、月、日的方法,只需要像下面这样调用一个方法:

deadline.set(2001, Calendar.APRIL, 15);

最后,还可以为给定的日历对象增加天数、星期数、月数等:

deadline.add(Calendar.MONTH, 3); // move deadline by 3 months

如果所传递的数值是一个负数,那么日期就向后移。

get方法与set和add方法在概念上是有区别的。get方法仅仅查看并返回对象的状态,而set和add方法却对对象的状态进行修改。对实例域做出修改的方法被称为更改器方法,仅访问实例域而不加修改的方法被称为访问器方法。

通常的习惯是在访问器方法名前面加上前缀get,在更改器方法前面加上前缀set。例如,在GregorianCalendar类有getTime方法和setTime方法,它们分别用来获得和设置日历对象所表达的时间点。

Date time = calendar.getTime( );

calendar.setTime(time);

这些方法在进行GregorianCalendar和Date类之间的转换时特别有用。这里有一个例子。假定希望知道年、月、日,并且希望创建一个具有这样的时间值的Date对象。由于Date类不知道如何操作日历,所以需要首先构造一个GregorianCalendar对象,然后再调用getTime方法得到一个日期对象:

GregorianCalendar calendar = new GregorianCalendar(year, month, day);

Date hireDay = calendar.getTime( );

与之相反,如果希望得到Date对象中的年、月、日信息,需要构造一个GregorianCalendar对象,设置时间,然后再调用get方法:

GregorianCalendar calendar = new GregorianCalendar( );

calendar.setTime(hireDay);

int year = calendar.get(Calendar.YEAR);

下面用一个应用GregorianCalendar类的程序来结束本节内容的阐述。这个程序将显示当前月的日历,其格式为:

Sun Mon Tue Wed Thu Fri Sat

1

2 3 4 5 6 7 8

9 10 11 12 13 14 15

16 17 18 19* 20 21 22

23 24 25 26 27 28 29

30 31

当前的日用一个 * 号标注,并且这个程序还能够计算星期几。

下面看一下这个程序的关键步骤。首先,构造一个日历对象,并用当前的日期和时间进行初始化。(对于这个应用程序,并不必在意实际的时间。)

GregorianCalendar d = new GregorianCalendar( );

经过两次调用get方法获得了当时的日、月。

int today = d.get(Calendar.DAY_OF_MONTH);

int month = d.get(Calendar.MONTH);

然后,将d设置为这个月的第一天,并获得这一天为星期几。

d.set(Calendar.DAY_OF_MONTH, 1);

int weekday = d.get(Calendar.DAY_OF_WEEK);

如果这个月的第一天是星期日,变量weekday被设置为1(即Calendar.SUNDAY);如果这个月的第一天是星期一,则设置为2(即Calendar.MONDAY),以此类推。

随后,输出标题和空格作为日历的第一行。

如果日期小于10,则先打印一个空格,再打印日期;如果是当前日,则打印日期之后再打印一个*。每一个星期天,重新换一行。

然后,将d设置为下一天:

d.add(Calendar.DAY_OF_MONTH, 1);

什么时候结束呢?我们并不知道这个月有31天、30天、29天,还是28天。其实,只要d还指示当月,就应该继续迭代。

do
{
. . .
}
while (d.get(Calendar.MONTH) == month);

一旦d进入了下一月,程序就终止执行。

例4-1给出了完整的程序。

正如所看到的那样,日历程序设计包含很多复杂问题,例如:某一天是星期几,每个月有多少天等。有了GregorianCalendar类,一切就变得简单了。我们并不必知道GregorianCalendar类是如何计算星期数和每月天数的,而只需要使用类提供的接口:get方法、set方法以及add方法就可以了。

这个例子程序的关键在于告诉我们:可以使用类的接口来解决复杂任务,而不必了解其中的实现细节。

例4-1 CalendarTest.java

java.util.GregorianCalendar 1.1

? GregorianCalendar( )

构造一个日历对象,用来表示默认地区、默认时区的当前时间。

? GregorianCalendar(int year, int month, int day)

用指定的日期信息构造一个Gregorian日历对象。

参数:year 该日期所在的年份

month 该日期所在的月份。此值以0为基准;例如,0表示一月

day 该月份中的日期

? GregorianCalendar(int year, int month, int day, int hour, int minutes, int seconds)

用给定的日期和时间信息构造一个Gregorian日历。

参数:year 该日期所在的年份

month 该日期所在的月份。此值以0为基准;例如,0表示一月

day 该月份中的日期

hour 小时(0~23)

minutes 分钟(0~59)

seconds 秒(0~59)

? int get(int field)

返回给定域的值。

参数:field

可以是下述选项之一:Calendar.ERA、Calendar.YEAR、Calendar.MONTH、

Calendar.WEEK_OF_YEAR、Calendar.WEEK_OF_MONTH、Calendar.DAY_

OF_MONTH、Calendar.DAY_OF_YEAR、Calendar.DAY_OF_WEEK、Calendar.DAY_

OF_WEEK_IN_MONTH、Calendar.AM_PM、Calendar.HOUR、Calendar.HOUR_

OF_DAY、Calendar.MINUTE、Calendar.SECOND、Calendar.MILLISECOND、

Calendar.ZONE_OFFSET、Calendar.DST_OFFSET

? void set(int field, int value)

设置特定域的值。

参数:field get接收的常量之一

value 新值

? void set(int year, int month, int day)

将日期域设置为新日期。

参数:year 日期所在年份

month 日期所在月份。此值是以0为基准的;例如,0表示一月

day 该月份中的日期

? void set(int year, int month, int day, int hour, int minutes, int seconds)

将日期和时间域设置为新值。

参数:year 日期所在年份

month 日期所在月份。此值是以0为基准的;例如,0表示一月

day 该月份中的日期

hour 小时(0~23)

minutes 分钟(0~59)

seconds 秒(0~59)

? void add(int field, int amount)

这是一个可以对日期信息实施算术运算的方法。对给定的时间域增加指定数量的时间。例如,可以通过调用c.add(Calendar.DAY_OF_MONTH, 7),将当前的日历日期加上7。

参数:field 需要修改的域(可以使用get方法文档中给出的一个常量)

amount 域被改变的数量(可以是负值)

? void setTime(Date time)

将日历设置为指定的时间点。

参数:time 时间点

? Date getTime( )

获取这个日历对象当前值所表达的时间点。

觉得文章不错的话,可以转发此文关注小编,之后持续更新干货文章!!!

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码