В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.
При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.
Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».
Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this
. Возьмем этот пример:
public class Some {
private int id;
public int getId(){
return this.id;
}
public setId( int newId ) {
this.id = newId;
}
}
И в другом месте вашего кода:
Some reference = new Some(); // Point to a new object of type Some()
Some otherReference = null; // Initiallly this points to NULL
reference.setId( 1 ); // Execute setId method, now private var id is 1
System.out.println( reference.getId() ); // Prints 1 to the console
otherReference = reference // Now they both point to the only object.
reference = null; // "reference" now point to null.
// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );
// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...
Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference
и otherReference
оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.
Еще несколько битов...
абсолютно необходимо иметь в распоряжении централизованную политику обработки исключений. Это может быть столь же просто как обертывание Main()
в попытке/выгоде, перестав работать быстро с корректным сообщением об ошибке пользователю. Это - обработчик исключений "последнего средства".
Упреждающие проверки всегда корректны по возможности, но не всегда прекрасны. Например, между кодом, где Вы проверяете на существование файла и следующую строку, где Вы открываете его, файл, возможно, был удален, или некоторая другая проблема может препятствовать Вашему доступу. Вам все еще нужна попытка/выгода/наконец в том мире. Используйте и упреждающую проверку и попытку/выгоду/наконец как соответствующие.
Никогда не "глотают" исключение, кроме наиболее хорошо зарегистрированных случаев, когда Вы абсолютно, положительно уверены, что выданное исключение приемлемо. Это никогда не будет почти иметь место. (И если это, удостоверьтесь, что Вы глотаете только конкретный , класс исключений - не делает никогда ласточка System.Exception
.)
При создании библиотек (используемый приложением), не глотайте исключения, и не бойтесь позволить пузырю исключений. Не повторно бросайте, если у Вас нет чего-то полезного для добавления. Не делайте никогда (в C#), делают это:
throw ex;
, Поскольку Вы сотрете стек вызовов. Если необходимо повторно бросить (который иногда необходим, такой как тогда, когда с помощью Блока Обработки исключений Библиотеки Предприятия), используйте следующее:
throw;
В конце дня, очень подавляющее большинство исключений, выданных запущенным приложением, должно быть представлено где-нибудь. Они не должны быть представлены конечным пользователям (поскольку они часто содержат собственные или в других отношениях ценные данные), а скорее обычно регистрировавшийся, с администраторами, уведомленными относительно исключения. Пользователю можно подарить универсальное диалоговое окно, возможно, ссылочный номер, для хранения вещей простыми.
Обработка исключений в.NET является большим количеством искусства, чем наука. У всех будет их избранное для совместного использования здесь. Это всего несколько подсказок, я взял.NET использования со дня 1, методы, которые убрались подобру-поздорову больше чем в одном случае. Ваш пробег может варьироваться.
Я глубоко согласовываю правило:
причина состоит в том что:
ForceAssert. AlwaysAssert является моим персональным способом Трассировки. Утверждайте только независимо от того, определяется ли макрос ОТЛАДКИ/ТРАССИРОВКИ.
цикл разработки, возможно: Я заметил, что ужасные Утверждают диалоговое окно, или кто-то еще жалуется мне об этом, тогда я возвращаюсь к коду и выясняю причину повысить исключение и решить, как обработать его.
этим путем я могу записать МОЙ код в скором времени и защитил меня от неизвестного домена, но всегда быть замеченным, если аварийные вещи произошли этим путем система, стало безопасным и больше безопасности.
я знаю многих из Вас, привычка соглашается со мной, потому что разработчик должен известный каждая деталь его кода, откровенно говоря, я - также пурист в былые времена. Но в наше время я узнал, что вышеупомянутая политика более прагматична.
Для кода WinForms, золотое правило, которое я всегда соблюдаю:
, это будет, защищал Ваш UI, являющийся всегда применимым.
Для хита производительности, потеря производительности только происходит, когда код reachs выгода, выполняя код попытки без фактического повышенного исключения не имеет никакого значительного эффекта.
Исключение должно произойтись с небольшим шансом, иначе это не исключения.
n мой опыт я счел целесообразным ловить исключения, когда я знаю, что собираюсь быть созданием их. Для экземпляров, когда я нахожусь в веб-приложении и я делаю Ответ. Перенаправление, я знаю, что буду получать Систему. ThreadAbortException. Так как это является намеренным, я просто имею выгоду для определенного типа и просто глотаю его.
try
{
/*Doing stuff that may cause an exception*/
Response.Redirect("http:\\www.somewhereelse.com");
}
catch (ThreadAbortException tex){/*Ignore*/}
catch (Exception ex){/*HandleException*/}
При переброске исключения бросок ключевого слова им сам. Это бросит перехваченную исключительную ситуацию и все еще будет в состоянии использовать отслеживание стека для наблюдения, куда это прибыло из.
Try
{
int a = 10 / 0;
}
catch(exception e){
//error logging
throw;
}
выполнение этого заставит отслеживание стека заканчиваться в операторе выгоды. (избегайте этого)
catch(Exception e)
// logging
throw e;
}
Одна вещь, которую я изучил очень быстро, состояла в том, чтобы включить абсолютно каждый блок кода, который взаимодействует с что-либо внешняя сторона поток моей программы (т.е. Файловая система, Вызовы Базы данных, Ввод данных пользователем) с блоками try-catch. Выгода попытки может подвергнуться хиту производительности, но обычно в этих местах в Вашем коде это не будет примечательно, и это заплатит за себя с безопасностью.
я использовал пустые блоки выгоды в местах, где пользователь мог бы сделать что-то, что не "действительно неправильно", но это может выдать исключение... пример, который приходит на ум, находится в GridView, если пользователь DoubleCLicks серая ячейка заполнителя вверху слева, это запустит событие CellDoubleClick, но ячейку, не принадлежит строке. В этом случае Вы не делаете действительно потребность добавить сообщение, но если Вы не поймаете ее, то она бросит ошибку необработанного исключения в пользователя.
Исключения являются дорогими, но необходимыми. Вы не должны переноситься, все в выгоде попытки кроме Вас действительно должно гарантировать, что исключения всегда пойманы в конечном счете. Большая часть его будет зависеть от Вашего дизайна.
не повторно бросают, если разрешение исключению повыситься сделает точно также. Никогда не позволяйте ошибкам передать незамеченный.
пример:
void Main()
{
try {
DoStuff();
}
catch(Exception ex) {
LogStuff(ex.ToString());
}
void DoStuff() {
... Stuff ...
}
, Если DoStuff идет не так, как надо, Вы захотите его к залогу так или иначе. Исключение будет выдано до основного, и Вы будете видеть поезд событий в отслеживании стека напр.
, Когда я должен повторно бросить исключение?
Везде, но методы конечного пользователя... обработчики щелчков кнопки Мне нравится
я должен попытаться иметь центральный механизм обработки ошибок некоторого вида?
я пишу, что файл журнала... довольно легкий для приложения
WinForm, Делает обрабатывающие исключения, которые могли бы быть выданы, производительность совершила нападки по сравнению с упреждающим тестированием вещей как то, существует ли файл на диске?
я не уверен в этом, но я полагаю, что это - хорошая практика к thow исключениям... Я подразумеваю, что можно спросить, существует ли файл и если он не бросает FileNotFoundException
, Должен весь исполняемый код быть включенным в try-catch-finally блоки?
yeap
Является там какими-либо временами, когда пустой блок выгоды мог бы быть приемлемым?
Да, скажем, Вы хотите показать дату, но у Вас нет подсказки, как та дата была хранилищами (dd/mm/yyyy, mm/dd/yyyy, и т.д.) Вы пробуете tp, анализируют его, но если это перестало работать, просто продолжают идти..., если это не важно Вам... Я сказал бы да, существует
Я просто ухожу, но дам Вам краткий шанс вниз на том, где использовать обработку исключений. Я попытаюсь обратиться к Вашим другим точкам, когда я возвращусь:)
причина *Within. Нет никакой потребности проверить, чтобы видеть, говорят ли, что космический луч поразил Ваши данные, вызывающие паре битов быть зеркально отраженным. Понимание, что "разумно", является полученным навыком для инженера. Трудно определить количество, все же легкий постигнуть интуитивно. Таким образом, я могу легко объяснить, почему я использую попытку/выгоду в каком-то конкретном экземпляре, все же мне трудно пропитывать другого с этим тем же знанием.
я для каждый склонен держаться далеко от в большой степени основанной на исключении архитектуры. попытка/выгода не имеет хита производительности как такового, хит входит, когда исключение выдается, и коду, возможно, придется идти по нескольким уровням стека вызовов, прежде чем что-то обработает его.
Мне нравится философия не ловли чего-либо, что я не предназначаю на обработке, безотносительно обработки средств в моем конкретном контексте.
я ненавижу его, когда я вижу код, такой как:
try
{
// some stuff is done here
}
catch
{
}
я время от времени видел это, и довольно трудно найти проблемы, когда кто-то 'ест' исключения. Коллега, которого я имел, делает это, и это имеет тенденцию заканчивать тем, что было участником непрекращающегося потока проблем.
я повторно бросаю, если существует что-то, что мой конкретный класс должен сделать в ответ на исключение, но проблема должна пузыриться к однако названному метод, где это произошло.
я думаю, что код должен быть записан заранее и это, исключения должны быть для исключительных ситуаций, чтобы не постараться не тестировать на условия.
Вот несколько инструкций, за которыми я следую
Сбой Быстро: Это - больше генерирующейся инструкции по исключению Для каждого предположения, что Вы делаете и каждый параметр, что Вы входите в функцию, делают проверку, чтобы удостовериться, что Вы начинаетесь с правильными данными и что предположения, которые Вы делаете, корректны. Типичные проверки включают, аргумент, не пустой, аргумент в ожидаемом диапазоне и т.д.
При переброске отслеживания стека заповедника - Это просто переводит в использование броска, когда перебросок вместо выдает новое Исключение (). Кроме того, если Вы чувствуете, что можно добавить, что больше информации тогда обертывает исходное исключение как внутреннее исключение. Но если Вы ловите исключение только для входа, оно тогда определенно использует бросок;
не ловят исключения, которые Вы не можете обработать, не волнуйтесь о вещах как OutOfMemoryException, потому что, если они происходят, Вы не будете в состоянии сделать много так или иначе.
Действительно сцепляют глобальные обработчики исключений и удостоверяются, что зарегистрировали как можно больше информации. Поскольку winforms сцепляют обоих appdomain и распараллеливают события необработанного исключения.
Производительность должна только быть учтена, когда Вы проанализировали код и видели, что это вызывает узкое место производительности, по умолчанию оптимизируйте для удобочитаемости и дизайна. Таким образом о Вашем исходном вопросе на проверке существования файла, я сказал бы, что это зависит, Если можно сделать что-то о файле, не являющемся там, тогда да делают ту проверку иначе, если все, что Вы собираетесь сделать, выдают исключение, если файл не там тогда я не вижу точку.
существуют определенно времена, когда пустые блоки выгоды требуются, я думаю люди, которые говорят, иначе не работали над кодовыми базами, которые развились по нескольким выпускам. Но они должны быть прокомментированы и рассмотрены, чтобы удостовериться, что они действительно необходимы. Самым типичным примером являются разработчики, использующие попытку/выгоду преобразовать строку в целое число вместо того, чтобы использовать ParseInt ().
, Если Вы ожидаете, вызывающая сторона Вашего кода, чтобы быть в состоянии обработать состояния ошибки тогда создает пользовательские исключения, которые детализируют то, что ООН excepected ситуация, и предоставьте релевантную информацию. Иначе просто придерживайтесь встроенных типов исключительной ситуации как можно больше.
Весь совет, отправленный здесь до сих пор, хорош и стоит учесть.
Одной вещью, на которой я хотел бы подробно остановиться, является Ваш вопрос, "Делают обрабатывающие исключения, которые могли бы быть выданы, производительность совершила нападки по сравнению с упреждающим тестированием вещей как то, существует ли файл на диске?"
наивное эмпирическое правило является "блоками попытки/выгоды, являются дорогими". Это не на самом деле верно. Попытка не является дорогой. Это - ловля, где система должна создать Объект исключения и загрузить его отслеживанием стека, это дорого. Существует много случаев, в которых исключение является, ну, в общем, достаточно исключительным, что оно прекрасно подходит для обертывания кода в блок попытки/выгоды.
, Например, если Вы заполняете Словарь, это:
try
{
dict.Add(key, value);
}
catch(KeyException)
{
}
часто быстрее, чем выполнение этого:
if (!dict.ContainsKey(key))
{
dict.Add(key, value);
}
для каждого объекта Вы добавляете, потому что исключение только выдается, когда Вы добавляете дублирующийся ключ. (Агрегатные запросы LINQ делают это.)
В примере Вы дали, я буду использовать попытку/выгоду почти без взглядов. Во-первых, просто потому что файл существует, когда Вы проверяете на него, не означает, что он собирается существовать при открытии его таким образом, необходимо действительно обработать исключение так или иначе.
119-секундный, и я думаю, что еще более важно, если Ваш a) Ваш процесс открывает тысячи файлов и b) разногласия файла, который это пытается открыть не существующий, не являются тривиально низкими, хит производительности создания исключения не является чем-то, что Вы когда-либо собираетесь заметить. Вообще говоря, когда Ваша программа пытается открыть файл, она только пытается открыть один файл. Это - случай, где запись более безопасного кода почти наверняка будет лучше, чем запись самого быстрого кода.
Существует превосходный код статья CodeProject здесь . Вот несколько выделений:
Золотое правило, которые попытались придерживаться, обрабатывают исключение максимально близко к источнику.
, Если необходимо повторно бросить попытку исключения добавить к нему, повторно бросив FileNotFoundException, не помогает многому, но бросок ConfigurationFileNotFoundException позволит ему получаться и реагироваться где-нибудь цепочка.
Другое правило, за которым я пытаюсь следовать, не состоит в том, чтобы использовать попытку/выгоду в качестве формы процесса выполнения программы, таким образом, я действительно проверяю файлы/соединения, удостоверяюсь, что объекты инициировались, ect.. до использования их. Попытка/выгода должна быть для Исключений, вещи, которыми Вы не можете управлять.
Что касается пустого блока выгоды, если Вы делаете что-либо важное в коде, который генерировал исключение, необходимо повторно бросить исключение как минимум. Если нет никаких последствий кода, который выдал исключение, не работающее, почему Вы писали его во-первых.
Обратите внимание, что в Windows Forms есть собственный механизм обработки исключений. Если кнопка в форме нажата, и ее обработчик выдает исключение, которое не перехвачено в обработчике, Windows Forms отобразит свой собственный диалог необработанных исключений.
Чтобы не отображать диалог необработанных исключений, и перехватывать такие исключения для ведения журнала и / или для предоставления собственного диалога об ошибках, который вы можете прикрепить к событию Application.ThreadException перед вызовом Application.Run () в вашем методе Main ().