3

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

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

这是我想做的,是不允许的

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

保持此日期字段“最终”的推荐方法是什么?

4

4 回答 4

9

好吧,您可以使用静态初始化程序块:

public static final Date MY_DATE;

static {
    try {
       MY_DATE = Util.getDateFromString("20000101");
    } catch (ParseException e) {
       // Whatever you want to do here. You might want to throw
       // an unchecked exception, or you might want to use some fallback value.
       // If you want to use a fallback value, you'd need to use a local
       // variable for the result of parsing, to make sure you only have a
       // single assignment to the final variable.
    }
}

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

从 Java 8 开始,该java.time包最适合用于几乎所有日期/时间工作,您可以在其中编写:

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

在 Java 8 之前,我建议您使用Joda Time,它有许多不可变的日期/时间类型——它是一个更好的处理日期和时间的库。看起来你想要:

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

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

于 2011-12-12T07:21:20.623 回答
2

我的天啊!我终于以更好、更精英、更优雅的答案超越了 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();}
};
于 2011-12-12T10:32:03.967 回答
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 是敷衍的。

于 2011-12-12T12:08:08.397 回答
0

它已在评论中说明,但为了更明确:

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

仅当您可以忍受分配给公共静态决赛的可变日期时才这样做。

于 2015-09-09T11:57:28.613 回答