我何时使用New来实例化一个类

时间:2011-12-28 10:34:00

标签: java instantiation

我正在阅读一个教程,教师似乎掩盖了一些没有意义的事情

在Java中,如果我想要实例化一个新的Gregorgian日期对象,我会使用:

GregorianCalendar gc= new GregorianCalendar (2010,1,14);

但如果我想使用数据格式对象,我会使用:

DateFormat df = DateFormat.getDateInstance();
  1. 我真的很想理解为什么dateformat不遵循实例化类的第一种方式?

  2. 我将如何知道未来的类似问题?

4 个答案:

答案 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)

  1. 这是因为它是一个抽象类,更多信息可以在这里找到:http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

  2. 同样,查看一个类是否抽象。

答案 3 :(得分:0)

Answer by Thorbjørn Ravn Andersen是正确的。这里还有一些想法。

避免使用旧的日期时间类

GregorianCalendar是与最早的Java版本捆绑在一起的可怕的日期时间类之一,该类由不了解日期时间处理的人员设计。

这些类在几年前被现代的 java.time 类所取代。 GregorianCalendar类专门由ZonedDateTime代替。

Table of date-time types in Java, both modern and legacy

不可变的类

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

Table of which java.time library to use with which version of Java or Android