我们有一个公共静态util方法,它可以解析一个字符串并返回一个Date对象,但是如果解析的字符串无法转换为Date对象,它也会抛出ParseException。
现在,在另一个类中,我希望使用上述util方法将静态最终Date初始化为值。但是假设util方法抛出ParseException,则不允许这样做。
这就是我想做的事情,这是不允许的
public static final MY_DATE = Util.getDateFromString('20000101');
将此日期字段设为“最终”的推荐方法是什么?
答案 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();
只有在您可以将可变日期分配给公共静态决赛时,才能执行此操作。