Является ли хорошей практикой применять обработку исключений в конструкторе?

Является ли законным иметь код обработки исключений в конструкторе класса или его следует избегать? Следует ли избегать генерации кода исключения в конструкторе?

Ответы

Ответ 1

Да, это совершенно разумно. Как еще у вас будет такое обстоятельство:

class List {
    public List(int length) {
        if(length < 0) {
            throw new ArgumentOutOfRangeException(
                "length",
                "length can not be negative"
            );
        }
        // okay, go!
    }
}

A List с отрицательной длиной, безусловно, является исключительным. Вы не можете позволить этому вернуться к вызывающей стороне и заставить их думать, что строительство было успешным. Какая альтернатива, функция члена экземпляра CheckIfConstructionSucceeded? Yucky.

Или как насчет

class FileParser {
    public FileParser(string path) {
        if(!File.Exists(path)) {
            throw new FileNotFoundException(path);
        }
        // okay, go!
    }
}

Опять же, это бросок, и ничто другое не приемлемо.

Ответ 2

Предполагая, что это С++, о котором вы говорите, создание исключений на самом деле является единственным способом оповестить ошибки в конструкторе, поэтому этого не следует избегать (*)

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

(*) Пока вы не из культа который избегает исключений в С++

Ответ 4

Я считаю, что это действительно так, чтобы исключить исключение в конструкторе, чтобы остановить создание объекта.

Ответ 5

В любом случае существует вероятность исключения исключения, "наилучшей практикой" является его обработка, конструктор или другое.

Он добавляет еще один уровень сложности к конструктору, так как вы должны убедиться, что все правильно инициализировано, даже если произошла ошибка, но это лучше, чем с ошибкой:)

Ответ 6

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

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

Ответ 7

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


Constructor(Param param){
  if(param == null)
    throw new IllegalArgumentException(...);
}