静态final java类中的Date字段

时间:2011-12-12 07:18:36

标签: java java.util.date

我们有一个公共静态util方法,它可以解析一个字符串并返回一个Date对象,但是如果解析的字符串无法转换为Date对象,它也会抛出ParseException。

现在,在另一个类中,我希望使用上述util方法将静态最终Date初始化为值。但是假设util方法抛出ParseException,则不允许这样做。

这就是我想做的事情,这是不允许的

public static final MY_DATE = Util.getDateFromString('20000101');

将此日期字段设为“最终”的推荐方法是什么?

4 个答案:

答案 0 :(得分:8)

可以使用静态初始化程序块:

public static final Date MY_DATE;

static {
    try {
       MY_DATE = Util.getDateFromString("20000101");
    } catch (ParseException e) {
       ...
    }
}

但是,我会建议不要这样做。 Date是一种可变类型 - 通过公共静态最终变量公开它是一个坏主意。

相反,我建议您使用具有许多不可变日期/时间类型的Joda Time - 并且是处理日期和时间的完全更好的库。看起来你想要:

public static final LocalDate START_OF_JANUARY_2000 = new LocalDate(2000, 1, 1);

请注意,即使您决定使用java.util.Date,在我的视图中解析字符串也没有多大意义 - 您在数值上知道这些值,为什么不呢?只是以这种方式供应它们?如果你没有一个合适的方法来构建一年/月/日的Date(大概是应用适当的时区),那么你可以轻松地写一个。

答案 1 :(得分:2)

OMG!我终于以更好,更精英,更优雅的答案来完成Jon Skeet!

一种巧妙的方法是使用带有实例块的匿名类,如下所示:

public static final Date MY_DATE = new Date() {{
    try {
        setTime(Util.getDateFromString("20000101").getTime());
    } catch (ParseException e) {
        throw new RuntimeException(e);
    }
}};

这是有效的,因为(显着)java.util.Date不是一成不变的!

要使Date不可变,因此在设计方面更可接受,也要覆盖setter方法:

public static final Date MY_DATE = new Date() {{
        try {
            super.setTime(Util.getDateFromString("20000101").getTime());
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
    // Formatted for brevity :)
    @Override public void setYear(int year) { throw new UnsupportedOperationException();}
    @Override public void setMonth(int month) {throw new UnsupportedOperationException();}
    @Override public void setDate(int date) {throw new UnsupportedOperationException();}
    @Override public void setHours(int hours) {throw new UnsupportedOperationException();}
    @Override public void setMinutes(int minutes) {throw new UnsupportedOperationException();}
    @Override public void setSeconds(int seconds) {throw new UnsupportedOperationException();}
    @Override public void setTime(long time) {throw new UnsupportedOperationException();}
};

答案 2 :(得分:1)

另一种方法是,如果您确定实际获取声明的异常,则在本地或在Util中创建另一个方法,将ParseException包装在未经检查的异常中,如这样:

public static final Date MY_DATE = getDateFromStringWithoutExploding("20000101");

private static Date getDateFromStringWithoutExploding(String dateString) {
    try {
        return Util.getDateFromStringWithoutExploding(dateString);
    catch(ParseException e) {
        throw new IllegalArgumentException(e);
    }
}

这是合理的,实际上反映了正在发生的事情 - 你知道你传入的日期字符串是好的,所以try-catch是敷衍了事。

答案 3 :(得分:0)

在评论中已经说明了这一点,但为了使其更明确:

public static final MY_DATE = new GregorianCalendar(2000, 1, 1).getTime();

只有在您可以将可变日期分配给公共静态决赛时,才能执行此操作。