现在大多数人都非常清楚地意识到,用于处理日历日期的Java API(特别是类java.util.Date
和java.util.Calendar
)是一个糟糕的混乱。
脱离我的头顶:
This post总结得很好,JSR-310也解决了这些问题。
现在我的问题是:
这些类是如何进入Java SDK的?大多数这些问题看起来相当明显(特别是Date是可变的)并且应该很容易避免。那怎么回事?时间压力?或者回想起来的问题是否明显?
我意识到这不是一个严格的编程问题,但我发现理解API设计如何出错是很有趣的。毕竟,错误总是一个很好的学习机会(我很好奇)。
答案 0 :(得分:42)
有人说它比我说的好:
- 类
Date
表示特定时刻,以毫秒为单位 精确。这堂课的设计是一个非常糟糕的笑话 - 一个发人深省的 甚至优秀的程序员如何搞砸的例子。大部分方法都在 现在不推荐使用日期,替换为以下类中的方法。类
Calendar
是一个用于在Date
之间进行转换的抽象类 对象和一组整数字段,例如年,月,日和小时。类
GregorianCalendar
是JDK中Calendar
的唯一子类。 它执行日历系统的日期到字段转换 常用。 Sun从Taligent获得了这个过度工程的垃圾 - a 一个平均程序员如何搞砸的清醒示例。
来自 Java程序员常见问题,版本来自07.X.1998,作者Peter van der Linden - 虽然这部分已从更高版本中删除。
至于可变性,很多早期的JDK类都受到它的影响(Point
,Rectangle
,Dimension
,...)。错误的优化,我听到有人说。
我们的想法是,您希望能够重用对象(o.getPosition().x += 5
)而不是创建副本(o.setPosition(o.getPosition().add(5, 0))
),因为您必须使用不可变项。对于早期的虚拟机,这甚至可能是一个好主意,而最有可能的不是现代虚拟机。
答案 1 :(得分:20)
Java的早期API只不过是他们时代的产物。在此之后几年,不变性才成为一种流行的概念。你说不变性是“显而易见的”。现在可能是这样,但事实并非如此。就像依赖注入现在“显而易见”但不是10年前。
创建Calendar对象的费用也很高。
出于向后兼容的原因,它们仍然是这样。或许更不幸的是,一旦错误得以实现,旧的类没有被弃用,并且为所有API提供了新的日期/时间类。这在某种程度上发生在JDK 8采用JodaTime之类的API(java.time
,JSR 310),但实际上它太晚了。
答案 2 :(得分:8)
时间本身并不容易衡量和处理。只需查看维基百科关于time的文章的长度。然后,对时间本身有不同的理解:一个绝对的时间点(作为一个常数),一个特定地点的时间点,一个时间范围,时间的分辨率....
我记得,当我第一次看到java.util.Date(JDK 1.0?)时,我真的非常高兴。我所知道的语言没有这样的功能。我没有想过时间转换等。
我认为这很糟糕,因为如果你从一个理解水平(XMLGregorianCaldender vs. Date)和需求(纳秒,过去2030年)发展到更高水平,但保持旧的不变,那么所有变化都会变得一团糟。并且java.util.Date不是Exception。只需看看I / O子系统或从AWT到Swing的转换......
正因为如此,“我们有时应该按下重置按钮。” (谁说,顺便说一下?)
答案 3 :(得分:5)
您可能会发现以下帖子很有趣。它几乎解释了Calendar类如何首先进入Java API,并阐明了日期类的起源。