В C++ начинается время жизни объекта, когда конструктор заканчивает успешно. В конструкторе объект еще не существует.
Q: Что делает испускание исключения от среднего конструктора?
A: Это означает, что конструкция перестала работать, объект никогда не существовал, его время жизни никогда не начиналось. [источник]
Мой вопрос: то же сохраняется для Java? Что происходит, например, если я вручаю this
к другому объекту и затем моим сбоям конструктора?
Foo()
{
Bar.remember(this);
throw new IllegalStateException();
}
Действительно ли это четко определено? Делает Bar
теперь имеет ссылка на необъект?
Объект существует, но не был правильно инициализирован.
Это может произойти всякий раз, когда this
утекает во время построения (а не только когда вы генерируете исключение).
Это очень проблематичная ситуация, потому что некоторые общепринятые гарантии в этой ситуации не выполняются (например, поля final
могут изменить свое значение во время построения).
Поэтому вам определенно следует избегать утечки this
в конструктор.
Эта статья IBM developerWorks описывает меры предосторожности, которые следует принимать при создании объектов, и обоснование этих мер предосторожности. Хотя в статье этот предмет обсуждается в свете многопоточности, у вас могут возникнуть аналогичные проблемы в однопоточной среде, когда неизвестный / ненадежный код получает ссылку на this
во время построения.
Этот код не является безопасным для исключений и не будет безопасным для исключений в C ++. Это одна и та же ошибка независимо от того, какой язык вы используете.
Вы никогда не должны открывать в конструкторе такие ресурсы, как средство записи файлов. Вместо этого создайте метод инициализации и сделайте это оттуда. Тогда ты в безопасности.