59

我最近继承的应用程序充满了关于构造函数的弃用警告:

Date d = new Date(int year, int month, int day)

有谁知道或可以指出为什么像这样简单的东西被这样的东西“取代”的原因:

Date d = null;
Calendar cal = GregorianCalendar.getInstance();
cal.set(1900 + year, month, day);
d = cal.getTime();

现在,显然弃用警告本身不是问题,但你能想象如果这个构造函数被删除,数百万的 LOC 会痛苦地哭泣吗?

在我简短的基准测试中,后者需要大约 50% 的时间来执行。

4

6 回答 6

48

最初,Date旨在包含有关日期的所有逻辑,但 API 设计者最终意识到,他们迄今为止的 API 严重不足,无法干净地扩展以正确处理时区、语言环境、不同日历、夏令时等问题, ETC。

所以他们创建Calendar来处理所有这些复杂性,并降级Date为一个简单的时间戳,弃用其处理格式化、解析和单个日期字段的所有功能。

顺便说一句,在内部这些方法(例如Date(int, int, int)构造函数)现在调用Calendar了,所以如果你看到速度上的差异,那么你在调用时做错了Calendar

底线:不是 Java 的CalendarAPI 过于复杂,而是人类对日期的概念,唯一的问题Calendar是它提供的最常见用法的快捷方式并不多。

于 2009-01-20T09:57:14.077 回答
8

Java 日期 API 长期以来一直受到批评,例如这个线程

您可能想查看Joda-TimeApache Commons Lang以获取替代日期/时间实用程序。

于 2009-01-20T08:11:17.600 回答
7

答案是便携性。

Date不是很灵活。您可以定义日期,但不能转换为其他日历格式。因此 Sun 决定使用额外的类层次结构 ( Calendar) 以使其更加灵活。

尽管如此,它不是很方便。

于 2009-01-20T08:08:48.197 回答
5

主要是因为原来的 java.util.Date 过于臃肿,不完全了解时区,而且对国际化不友好。

但是,Date 仍在使用中,而且非常好,在值对象中,或者说是一种数据类型。只要您明确地使其不可变,您就可以轻松进行。我倾向于认为它必须是不可变的,出于其他目的,我们可以使用 Calendar 来操作。在预期有很多操作的地方,应该考虑类似 Joda-Time 之类的东西。

[已编辑]

只是不要在后面的代码中实例化日期。它没有用。您可能会为您的基准测试获得更好的结果。

于 2009-01-20T08:33:38.850 回答
3

当然,没有人使用任何其他日历格式,但新的 API 增加了为 99% 的常见情况编写的代码量,因此对于由 LoC 支付的 Java 程序员来说这是一个巨大的福音。

于 2009-01-20T11:59:18.090 回答
3

从技术上讲,Michael Borgwardt 给出了最好的答案。但是,为什么他将我们太阳系的布局方式归咎于人类呢?

好的,我们想出了秒、分钟和小时的概念。

但是地球的日子是近似的并不是我们的错(取决于我们是在谈论真正的太阳日、平均太阳日还是恒星日,每个日都是周期性和随机变化的)。地球绕太阳公转的时间大约是365 天不是我们的错,月球绕地球公转的时间大约是27.3 天也不是我们的错(取决于我们是否在谈论恒星、会合、热带月、异常月或龙(节点)月)。

您不高兴日历没有考虑所有这些细节吗?那么我们的软件错误可能确实取决于月相。

于 2011-03-22T14:13:14.107 回答