簡體   English   中英

java類中的靜態最終日期字段

[英]static final Date field in a java class

我們有一個公共靜態 util 方法,它可以解析一個字符串並返回一個 Date 對象,但它也會拋出 ParseException 以防解析的字符串無法轉換為 Date 對象。

現在,在另一個類中,我希望使用上述 util 方法將靜態最終 Date 初始化為一個值。 但鑒於 util 方法拋出 ParseException,這是不允許的。

這是我想做的,這是不允許的

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

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

好吧,您可以使用靜態初始化程序塊:

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 ,那么您可以輕松編寫一個。

我的天啊! 我終於以更好、更精英、更優雅的答案超越了 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();}
};

另一種方法,如果你確定你實際上不會得到聲明的異常,是在本地或在 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 是敷衍的。

它已在評論中說明,但為了使其更明確:

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

僅當您可以忍受分配給公共靜態最終結果的可變日期時才這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM