Вопрос по java, constructor, enums, singleton – Как вызвать исключение из конструктора enum?

10

Как я могу выбросить исключение из конструктора enum? например:

public enum RLoader {
  INSTANCE;
  private RLoader() throws IOException {
   ....
  }
}

выдает ошибку

Необработанный тип исключения IOException

Пожалуйста, не используйте синглтоны. Tom Hawtin - tackline
@ Петер Тёрёк, как лучше реализовать его вручную, как обычный класс? Я думаю, что можно использовать enum для реализации синглтона, как сказал <Effective Java>. bylijinnan
Я реализую Singleton, но как лучше реализовать его вручную как обычный класс? Мне все равно придется выбросить исключение из кода, вызываемого статическим инициализатором. Вы можете выбросить непроверенные исключения из конструктора enum. tekumara
есть что-топротивный о получении исключения только путем доступа к значению enum. Не так уж плохо, когда это единственный метод getInstance (). Kirk Woll
Почему вы хотите это сделать? Для меня это звучит как злоупотребление концепцией enum. Предполагается, что значения перечисления являются константами, создание которых ни от чего не зависит. Даже если технически вымог сделать это (бросив непроверенное исключение вместо проверенного), я бы посоветовал вам пересмотреть свой дизайн. Если вы пытаетесь реализовать Singleton через это перечисление, лучше реализовать его вручную, как обычный класс. Péter Török

Ваш Ответ

3   ответа
0

Вы пытаетесь бросить проверенныйException от конструктора.

Этот конструктор вызываетсяINSTANCE объявление enum entry, поэтому проверенное исключение не может быть обработано правильно.

Также, на мой взгляд, это плохой стиль - генерировать исключения из конструктора, так как конструктор обычно не должен выполнять какую-либо работу и особенно не создавать ошибок.

Также, если вы хотите броситьIOException Я предполагаю, что вы хотите инициализировать что-то из файла, поэтому вам следует рассмотреть эту статью надинамические перечисления.

Есть ли разница между генерацией исключения из метода фабрики и конструктора? Вы говорите помидор, я говорю помидор matt b
Исключительное использование фабричных методов для всех объектов? О бедный гореновый оператор. :) Kirk Woll
@Kirk Woll: Нет, не для всех экземпляров, а для того случая, когда требуется специальная проверка параметров конструктора. Обычно я использую принцип не выполнять работу внутри конструкторов, кроме заданий, поэтому я не программирую так же быстро, как вы :) Johannes Wachter
Если генерировать исключения из конструктора - это плохой стиль, что вы будете делать, если один из аргументов вашего конструктора недопустим и будет препятствовать функционированию вашего класса? Я предпочитаю быстро потерпеть неудачу, выдав исключение, чтобы получить значимый след стека. При этом, я согласен с вами, что ФП не должен пытаться бросить исключение вперечисляемые-х конструктор. Kirk Woll
@Kirk Woll: я предпочитаю использовать фабричные методы, которые обеспечивают достоверность параметров. Также я в основном фокусировался на проверенных исключениях, RuntimeException был бы лучшим способом сообщить об ошибке проверки IMO. Johannes Wachter
17

вместо этого выведите ExceptionInInitializerError.

Хотя это возможное решение, я не думаю, что имеет смысл решать проблему таким образом. Johannes Wachter
3

когда я хочу использовать перечисления в качестве ключей в некоторых классах настроек. В базе данных будет храниться строковое значение, что позволит нам изменять константы перечисления без необходимости обновлять базу данных (я знаю, что это немного уродливо). Я хотел добавить исключение времени выполнения в конструктор enum как способ контролировать длину строкового аргумента, чтобы избежать попадания в базу данных, а затем получить нарушение ограничения, когда я сам мог легко его обнаружить.

public enum GlobalSettingKey {
    EXAMPLE("example");

    private String value;

    private GlobalSettingKey(String value) {
        if (value.length() > 200) {
            throw new IllegalArgumentException("you can't do that");
        }
        this.value = value;
    }

    @Override
    public String toString() {
        return value;
    }
}

Когда я создал быстрый тест для этого, я обнаружил, что выброшенное исключение не мое, а ExceptionInInitializerError.

Может быть, это глупо, но я думаю, что это вполне допустимый сценарий, когда нужно генерировать исключение в статическом инициализаторе.

Но исходное исключение связано с ExceptionInInitializerError, поэтому, если вы вызовете для него 'getCause ()', вы получите исходное исключение. shrini1000

Похожие вопросы