我正在阅读一个教程,教师似乎掩盖了一些没有意义的事情
在Java中,如果我想要实例化一个新的Gregorgian日期对象,我会使用:
GregorianCalendar gc= new GregorianCalendar (2010,1,14);
但如果我想使用数据格式对象,我会使用:
DateFormat df = DateFormat.getDateInstance();
我真的很想理解为什么dateformat不遵循实例化类的第一种方式?
我将如何知道未来的类似问题?
答案 0 :(得分:4)
您应该始终查阅API文档,了解如何使用它。
new X()
总是创建一个新对象,所以如果你有多个地方需要它,你最终会得到多个X',如果单个X会这样做效率很低。
.getDateInstance()
调用是一个 Factory ,它允许API自行决定是将同一个X甚至多个调用者返回给每个调用者还是新调用者。对于非常昂贵但可重复使用/可共享的物体,这是您获得它们的典型方式。
Calendar API很久以前就已经捐赠给了Java,并且设计得不尽如人意。这些天在java中对“我有问题X with Calendar和/或java.util.Date”的典型响应是使用 设计良好的Joda库。
答案 1 :(得分:3)
简短的回答是核心Java API设计不当且不一致。这些不一致通常没有充分的理由,你只需要和他们一起生活。
更一般地说,像DateFormat.getDateInstance()
这样的工厂方法允许API根据情况选择不同的实现类,而直接使用构造函数意味着没有这种灵活性。
顺便说一下,除非您特别想要GregorianCalendar
,否则推荐的获取方法为Calendar.getInstance()
,如果您的语言环境合适,则会返回GregorianCalendar
。其他语言环境将返回不同的Calendar
实现。这与您的DateFormat
示例一致。
答案 2 :(得分:1)
这是因为它是一个抽象类,更多信息可以在这里找到:http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
同样,查看一个类是否抽象。
答案 3 :(得分:0)
Answer by Thorbjørn Ravn Andersen是正确的。这里还有一些想法。
GregorianCalendar
是与最早的Java版本捆绑在一起的可怕的日期时间类之一,该类由不了解日期时间处理的人员设计。
这些类在几年前被现代的 java.time 类所取代。 GregorianCalendar
类专门由ZonedDateTime
代替。
java.time 类被设计为immutable,使它们成为thread-safe。
这意味着您永远不会使用new
。而是调用工厂方法。了解naming conventions on such methods。
让我们捕捉通过特定地区(时区)人们使用的挂钟时间所看到的当前时刻。我们调用ZonedDateTime.now
来捕获当前时刻。如您在the source code中所见,ZonedDateTime
的构造函数被标记为private
,以防止我们通过new
进行实例化。在该类的内部,factory方法执行new
。您可以自己查看源代码,搜索new ZonedDateTime
。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
顺便说一句,如果必须使用GregorianCalendar
与尚未更新为 java.time 的旧代码进行互操作,则可以进行转换。请参阅添加到旧类中的新转换方法。
ZonedDateTime zdt = myGregCal.toZonedDateTime() ;
…和…
GregorianCalendar myGregCal = GregorianCalendar.from( zdt ) ;