为什么 "new Date(int year, int month, int day)" 被弃用了?

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();

很明显,弃用警告本身并不是问题,但是如果这个构造函数被删除了,可以想象有数百万行代码会发出哀嚎声。

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


4
第一行不是完全浪费时间吗?从cal到Calendar.getTime()可以得到一个日期,为什么还要用new Date()创建一个然后扔掉它?特别是如果你正在对此进行基准测试的话... - unwind
2
@unwind:很好的发现。为什么不写一篇文章呢? - Adeel Ansari
40
也许这是因为美国人期待的是Date(int year,int day,int month);-) - Skizz
1
“LOC” 是什么意思? - Nicolas Barbulesco
2
请注意,查看Java 8新的日期API!http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html - aldo.roman.nurena
显示剩余4条评论
6个回答

48

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

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

顺带一提,现在这些方法(例如 Date(int, int, int) 构造函数)内部调用了 Calendar,因此如果您看到速度上的差异,则在调用 Calendar 时可能出了问题。

总之:Java 的 Calendar API 并没有过度复杂,而是人们对日期的概念过于复杂。 Calendar 的唯一问题在于它没有提供常见用途的快捷方式。


java.util.Date 重用了 Gregorian Calendar 的静态实例,这至少令人感到有趣。但相较于为每个循环创建一个新的 Calendar 实例,它的性能会更好。 - Martin

8

我记得一段时间以前在Parleys上观看了有关Joda的演示,并且印象深刻。http://www.parleys.com/display/PARLEYS/Home#slide=1;title=JSR%20310%20-%20Date%20and%20Time%20API;talk=7602357。至于将其反向实现到数十万行代码中,我不太确定。 - Scott Bennett-McLeish
好的观点。Joda-Time后来被用作Java时间和日期API(java.time)开发的基础。从Java 8开始内置,也向下兼容到Java 6和7。这是我建议我们现在都使用的东西。 - Ole V.V.

7
答案是可移植性。 Date 类不是很灵活。你可以定义日期,但不能将其转换为其他日历格式。因此,Sun 决定使用额外的类层次结构(Calendar)使其更加灵活。
尽管如此,它还不是非常方便。

5
大多数是因为最初的java.util.Date过于臃肿,且未完全考虑时区和国际化友好性。
然而,在值对象中或作为数据类型中,Date仍然被广泛使用。只要您明确将其设置为不可变,就可以轻松地进行操作。我倾向于认为它必须是不可变的,因为我们有Calendar用于操作。在预期需要大量操作时,应考虑使用Joda-Time等工具。
[编辑]
只需不要在后面的代码中实例化Date即可。它没有任何用处。这样可以为您的基准测试实现更好的结果。

3
迈克尔·博格沃特的回答在技术上是最好的。但为什么他要责怪人类布置太阳系的方式呢?
好吧,我们想出了秒、分和小时的概念。但是,地球的日子是近似的(取决于我们是谈论真正的太阳日、平均太阳日还是恒星日,每种情况都会周期性和随机变化)。这不是我们的错,地球绕太阳公转的时间大约是365天,月球绕地球公转的时间大约是27.3天(取决于我们是谈论恒星、月相、热带、离心或龙腾月)。这也不是我们的错。
你不觉得很高兴日历没有考虑所有这些细节吗?否则,我们的软件错误可能确实取决于月相。

显而易见的船长再次出击!无需复制,只需指向。http://zh.wikipedia.org/wiki/格里历 - IceGlow

2
当然,没有人使用其他日历格式,但新API增加了99%常见情况下需要编写的代码量,因此对于按行计算工资的Java程序员来说,这是一个巨大的福利。

哈,这个时代还在使用代码行数作为生产力指标吗? - Scott Bennett-McLeish
希望不是这样,但或许生产如此 API 的 Sun 公司的那些家伙们没有听说事情已经改变了... - bobince

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接