The "problem" you link to, кажется, описывая эту ситуацию: жалоба
SomeObject so;
try {
// Do some work here ...
so = new SomeObject();
so.DoUsefulThings();
} finally {
so.CleanUp(); // Compiler error here
}
комментатора является то, что компилятор уклоняется в строке в разделе finally
, утверждая, что so
может быть инициализирован. Комментарий затем упоминает еще один способ написания кода, вероятно, что-то вроде этого:
// Do some work here ...
SomeObject so = new SomeObject();
try {
so.DoUsefulThings();
} finally {
so.CleanUp();
}
комментатора недоволен этим решением, потому что компилятор затем говорит, что код «должен быть в пределах попытки.» Я предполагаю, что это означает, что часть кода может вызвать исключение, которое больше не обрабатывается. Я не уверен. Ни одна из версий моего кода не обрабатывает никаких исключений, поэтому все исключения, связанные с первой версией, должны работать одинаково во втором.
В любом случае, эта вторая версия кода является правильным способом ее написания. В первой версии сообщение об ошибке компилятора было правильным. Переменная so
может быть неинициализирована.В частности, если конструктор SomeObject
терпит неудачу, so
не будет инициализирован, и поэтому будет предпринята попытка вызвать вызов so.CleanUp
. Всегда вводите try
раздел после вы приобрели ресурс, который завершает раздел finally
.
try
- finally
блок после so
инициализации есть только защитить экземпляр SomeObject
, чтобы убедиться, что он не получает очищены независимо от того, что еще происходит. Если есть другие вещей, которые должны работать, но они не связаны ли выделена экземпляр SomeObject
собственности, то они должны идти в другогоtry
- блок finally
, вероятно, тот, который облегает один я показал ,
Обязательные переменные, назначаемые вручную перед использованием, не приводят к возникновению реальных проблем. Это только приводит к незначительным неприятностям, но ваш код будет лучше для него. У вас будут переменные с более ограниченной областью, и try
- finally
блоки, которые не пытаются защитить слишком много.
Если локальные переменные имели значения по умолчанию, то so
в первом примере было бы null
. Это ничего бы не решило. Вместо того, чтобы получить ошибку времени компиляции в блоке finally
, у вас будет NullPointerException
, скрывающийся там, где может быть скрыть. Любое другое исключение может возникнуть в разделе «Сделайте некоторые работы здесь». (Или делать исключения в разделах finally
, которые автоматически соединяются с предыдущим исключением? Я не помню. Тем не менее, у вас было бы лишнее исключение на пути реального.)
Тот же вопрос: [http://stackoverflow.com/questions/268814/uninitialized-variables-and-members-in-java](http://stackoverflow.com/questions/268814/uninitialized-variables-and- members-in-java) –
Извините, что ... этот вопрос не появился, когда я вводил вопрос. Однако, я думаю, есть разница между двумя вопросами ... Я хочу знать, почему дизайнеры Java * спроектировал * это так, в то время как вопрос, на который вы указали, не спрашивает, что ... –
, потому что инициализация уже не была забавой. – Bastardo