статическое окончательное поле даты в Java-классе - PullRequest
3 голосов
/ 12 декабря 2011

У нас есть публичный статический метод util, который может анализировать строку и возвращать объект Date, но он также генерирует ParseException в случае, если проанализированная строка не может быть преобразована в объект Date.

Теперь в другомЯ хотел бы, чтобы статическая конечная дата инициализировалась значением, используя метод util, описанный выше.Но, учитывая, что метод util генерирует ParseException, это недопустимо.

Это то, что я хочу сделать, что недопустимо

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

Каков рекомендуемый способ сохранить эту датуполе 'финал'?

Ответы [ 4 ]

8 голосов
/ 12 декабря 2011

Ну, вы могли бы использовать статический блок инициализатора:

public static final Date MY_DATE;

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

Однако я бы посоветовал против этого. Date является изменяемым типом - выставлять его через открытую статическую переменную final - плохая идея.

Вместо этого я бы порекомендовал вам использовать Joda Time , который имеет много неизменных типов даты / времени - и является значительно лучшей библиотекой для работы с датами и временем. Похоже, вы хотели бы:

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

Обратите внимание, что даже если вы do решите пойти с java.util.Date, не имеет смысла анализировать строку в моем представлении - вы знаете значения численно, так почему бы просто не предоставить их сюда? Если у вас нет подходящего метода для построения Date из года / месяца / дня (предположительно с применением соответствующего часового пояса), то вы могли бы легко написать один.

2 голосов
/ 12 декабря 2011

OMG! Я наконец-то смог превзойти Джона Скита с лучшим, более элитным, более элегантным ответом!

Один из простых способов - использовать анонимный класс с блоком экземпляра, например так:

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

Это работает, потому что (замечательно) java.util.Date не является неизменным!

Чтобы сделать дату неизменной и, следовательно, более приемлемой с точки зрения дизайна, переопределите также методы установки:

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();}
};
1 голос
/ 12 декабря 2011

Другой способ, если вы уверены, что на самом деле не получит объявленное исключение, это создать другой метод, локально или в 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 является небрежным.

0 голосов
/ 09 сентября 2015

Это было указано в комментарии, но для большей ясности:

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

Делайте это только в том случае, если вы можете жить с изменяемой датой, назначенной общедоступному статическому финалу.

...