Get Adobe Flash player

Программируя на языке Java, вы будете тратить значительно больше времени на обработку исключений, чем на их создание и выбрасывание. Пока имейте в виду, что опасный метод, который вы вызываете, выбрасывает исключение обратно вам — тому, кто его вызвал. На практике вы можете оказаться по обе стороны. На самом деле не имеет значения, кто пишет код. Важно знать, какой метод выбрасывает исключение, а какой метод его отлавливает. ==- При написании кода, который может выбросить исключение, необходимо объявить это исключение.
Если при выполнении программы что-то пошло не так, метод может выбросить исключение. Исключение — это всегда объект типа Exception (как вы помните из главы о полиморфизме, это может быть экземпляр класса, находящийся в иерархии наследования ниже Exception). Компилятор не обращает внимания на исключения типа RuntimeException. Такие исключения необязательно объявлять или заключать в блок try/catch (хотя можно сделать и то и другое).
Все исключения, которые интересны компилятору, называются проверяемыми (в том смысле, что компилятор их проверяет). Не проверяются только исключения, имеющие тип RuntimeException. Все остальные должны быть объявлены и обработаны согласно правилам.
Метод выбрасывает исключение с помощью ключевого слова throw, за которым следует объект Exception: throw new NoCaffeineException();
Метод, который может выбросить проверяемое исключение, обязан объявить об этом с помощью выражения throws Exception. Если в своем коде вы вызываете метод, который может выбросить проверяемое исключение, то должны убедить компилятор в том, что меры предосторожности были приняты.
Если вы готовы обработать исключение, заключите вызов в блок try, поместив код по обработке/восстановлению в блок catch. Если вы не готовы обработать исключение, то можете «пробросить» его дальше, удовлетворив тем самым компилятор. Когда вы вызываете опасный метод, может случиться одно из двух: либо этот метод успешно выполнится и блок try завершится, либо он выбросит исключение вызвавшему его методу.
Компилятор проверяет все исключения, кроме RuntimeException, Компилятор гарантирует следующее. Если вы выбрасываете исключения в своем коде, то должны объявить его при объявлении метода с помощью ключевого слова throws.
Если вы вызываете метод, который выбрасывает исключение (то есть метод, объявляющий о выбросе исключения), то должны подтвердить, что осознаете
возможность этого выброса. Основной способ удовлетворить компилятор — заключить вызов в блок try/catch
Большинство исключений типа RuntimeException возникают из-за логики вашего кода, а не из-за ситуаций, происходящих при выполнении программы, которые вы не можете предсказать или предотвратить. Вы не можете гарантировать, что файл будет именно там, где ожидается. Вы не можете гарантировать, что сервер будет работать. Но вы можете убедиться в том, что ваш код не использует индекс, выходящий за пределы массива (вот для чего нужен атрибут length). Вы хотите, чтобы исключение RuntimeException случилось во время разработки и тестирования. Вы не хотите добавлять лишние блоки try/catch для отлова ситуаций, которые, скорее всего, не произойдут.
Блок try/catch предназначен для обработки исключительных ситуаций, а не дефектов кода. Используйте его, чтобы исправлять действия, успешность которых вы не можете гарантировать. В крайнем случае выведите пользователю сообщение и трассировку стека, чтобы была возможность выяснить, что произошло.

Finally: для действий которые нужно выполнить несмотря ии на что Если вы хотите что-нибудь приготовить, нужно сначала включить плиту. Если ваше блюдо полностью испортилось, нужно выключить плиту. Если у вас все получилось, нужно выключить плиту. Нужно выключить плиту несмотря ни на что!
Finally — это блок для кода, который должен выполниться независимо от того, было ли
выброшено исключение.
try {
turnOvenOn();
x.bake () ;
} catch (BakingException ex) {
ex.printStackTrace();
} finally {
turnOvenOff();
}
Без finally пришлось бы указывать метод rurnOvenOffO в обоих блоках — try и catch, так как нужно выключить плиту в любом случае. Блок finally позволяет поместить важный код для очистки в дном месте, избегая дублирования, пример которого приводится ниже:
try {
turnOvenOn();
x.bake () ;
turnOvenOff();
} catch (BakingException ex) {
ex.printStackTrace();
turnOvenOff();
}

Мы уже говорилц что метод может выбрасывать несколько исключений? Метод может выбрасывать сразу несколько исключений, если он в этом очень нуждается. Но при объявлении метода нужно указать все проверяемые исключения, которые он может выбросить (хотя, если два или больше из них имеют общего предка, можно ограничиться одним родительским классом). Перехват нескольких исключений Компилятор проконтролирует, обработали ли вы все проверяемые исключения, которые выбрасываются вызываемым методом. Размещайте блоки catch после try, один за другим.
Исключения поддерживают полиморфизм Не забывайте, что исключения — это объекты. От остальных объектов они отличаются лишь тем, что их можно выбросить. Таким образом, как и на любой добропорядочный объект, на Exception можно ссылаться с использованием полиморфизма. Основной плюс — метод не обязан объявлять все исключения, которые может выбросить; достаточно указать родительский класс. Это же касается и блоков catch — необязательно создавать их для каждого возможного исключения, если они и так их перехватывают. При объявлении вы используете родительский тип для выбрасываемых исключений.
Как вы поняли, можно отлавливать все с помощью единственного полиморфического блока catch, но это не значит, что нужно всегда так делать. Можете использовать при обработке исключений всего один блок catch, указывая родительский класс Exception. Тогда вы сумеете перехватить любое исключение, которое может быть выброшено.
try {
laundry.doLaundry();
} catch (Exception ex) {
// Восстановительный код..
}
Создавайте отдельные блоки catch для каждого исключения, которое нужно обработать уникальным образом. Например, если ваш код по-разному обрабатывает исключения TeeShirtException и LingerieException, создайте для каждого из них по блоку catch. Но если с остальными потомками ClothingException вы работаете одинаково, то просто добавьте это исключение в блок catch, чтобы обработать всех его потомков.
Множественные блоки catch должны располагаться по возрастанию: от наименьшего к наибольшему.
Нельзя размешать большие блоки catch над маленькими.
Если вы не хотите обрабатывать исключение, то можете пробросить его на уровень ниже, используя объявление. Когда вы вызываете опасный метод, компилятор должен об этом знать. В большинстве случаев необходимо лишь заключить вызов в блок try/catch. Но есть и другой вариант — можно просто пробросить исключение наверх, позволяя методу, вызвавшему ваш код, обработать его. Достаточно объявить, что вы выбрасываете исключение, даже если этого, строго говоря, не происходит. Вы просто позволяете исключению пройти мимо. Но если вы пробрасываете исключение, оказывается ненужным блок try/catch. Что же случается, -если опасный метод (doLaundryQ) действительно выбрасывает объект Exception? При выбросе исключения метод немедленно покидает стек, а само исключение передается следующему методу, который вызывал предыдущий. Но если вызывавший метод занимается пробрасыванием, у него нет блока catch, поэтому он покидает стек и передает исключение вниз по цепочке, и т. д. Когда же это закончится?

Пробрасывая исключение вы только откладываете неизбежное.
Либо обработайте, либо объявите. Это закон.
Итак, вы уже узнали два способа удовлетворить компилятор при вызове опасного метода (выбрасывающего исключение). Обработка Заключаем опасный метод в блок try/catch.
try {
laundry.doLaundry();
} catch(ClothingException cex)
// Восстановительный код»
Объявление (проброс) Объявляем о том, что оба метода (наш и вызываемый)
выбрасывают одни и те же исключения.
void foo() throws ClothingException {
laundry. doLaundry () ;
}
Но это приводит к тому, что все, кто вызывает метод f oo(), должны следовать закону «обработай или объяви». Если fоо() пробрасывает исключение (объявляя его), то main() при вызове метода должен обработать это исключение.

public class Washer {
Laundry laundry = new Laundry();
public void foo() throws ClothingException {
laundry.doLaundry();
}
public static void main (String[] args) {
Washer a = new Washer();
a.foo() ;// не скомпилируется поскольку метод foo() выбрасывает исключение
}
}

Правила для исключений:
1. Вы не можете использовать блоки catch finally без try.
2. Вы не можете добавлять код между try и catch.
3. За блоком try должны следовать catch или finall.
4. При использовании блока try только с finally (без catch) все равно нужно объявить исключение.
5.