Java: Исключение в конструкторах: проблематично или нет? - PullRequest
9 голосов
/ 23 сентября 2011

В последнее время я думаю о том, хорошо ли бросать конструктор из Java или нет.В настоящее время это то, что я собрал:

  1. Могут ли конструкторы генерировать исключения в Java?

    Здесь г-н StackOverflow (он же Джон Скит) не делаетпохоже, что-то против этого, но он намекнул на наличие исключений для подкласса.Что произойдет (что-нибудь плохое?), Когда подкласс вызовет исключения?

  2. http://futuretask.blogspot.com/2006/05/java-tip-10-constructor-exceptions-are.html

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

  3. Я думаю, что если бы статические фабричные методы (Effective Java 2nd ed., Item 1) использовались вместо открытых конструкторов, мы могли бы безопасно удалить исключенияот конструкторов до статического метода фабрики.Является ли это допустимым способом избежать исключений конструктора и полезно ли оно или используется где-либо?

Любые входные данные полезны и приветствуются.Спасибо!

Ответы [ 3 ]

8 голосов
/ 23 сентября 2011

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

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

8 голосов
/ 23 сентября 2011

Моя точка зрения о том, что подкласс создает исключение, выглядит следующим образом:

public class Parent {
    private final InputStream stream;

    public Parent() {
        stream = new FileInputStream(...);
    }

    public void close() throws IOException {
        stream.close();
    }
}

public class Child extends Parent {
    public Child() {
        // Implicit call to super()
        if (someCondition) {
            throw new RuntimeException();
        }
    }
}

Теперь класс Child действительно должен вызвать close(), если он собирается броситьисключение.Конечно, если close() переопределено еще одним уровнем наследования, это может также вызвать проблемы.Еще один пример того, как наследование становится беспорядочным.

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

Фабричные методы могут потенциально помочь, но для вызывающего абонента результат тот же: они не доходят доувидеть частично построенный объект.Если вам действительно не понадобится для выполнения чего-то вроде очистки объекта, который был построен, но затем не прошел какой-либо элемент проверки, я не думаю, что это должно быть причиной для использования фабричных методов вместо конструкторов.(Есть другие причины для этого, но это другое дело.)

1 голос
/ 23 сентября 2011

Я полагаю, что генерировать исключения из конструкторов - это хорошо, тем более что проверяется наличие предварительных условий для успешного создания объекта, например IllegalArgumentException.Однако я не верю, что конструкторы являются подходящим местом для обработки бизнес-логики или создания бизнес-исключений / пользовательских исключений.

Что касается приведенных выше причин, по которым не генерируется исключение, ИМХО, они довольно надуманные;Суть в том, что если неосторожный разработчик желает совершить что-то плохое, он может найти множество способов сделать это, и никто не остановится, пока разработчик сам не пересмотрит код / ​​не последует рекомендациям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...