Главная » Разработка для Android » Исключения- JAVA ДЛЯ ANDROID

0

 

В языке Java исключения используются как удобный инструмент, позволяющий справляться с необычными ситуациями. Зачастую такие условия сводятся к возникновению ошибок.

Код, пытающийся произвести синтаксический разбор веб-страницы, не может, например, продолжить работу, если у него не получается считать страницу из сети. Разумеется, можно проверить результаты попытки такого считывания, и продолжить работу лишь в том случае, если попытка окажется удачной, как показано в следующем примере:

С применением исключений код становится более красивым и надежным:

В этом варианте кода каждый метод, вызываемый от getPage, использует исключения для моментального «короткого замыкания» всей дальнейшей обработки, если вдруг что-то пойдет неправильно. Принято говорить, что методы выбрасывают исключения. Например, метод getActions может выглядеть примерно так:

При выполнении утверждения throw обработка сразу же прекращается и начинается со следующего блока перехвата (catch block). Вот пример блока «попытка-перехват» (try-catch):

Этот код выполняет повторные попытки при отказе сети. Обратите внимание, что он даже не находится в методе readPageFromNet, который выбросил исключение NetworkException. Когда мы говорим, что обработка возобновляется с ближайшего блока «попытка-перехват», мы подходим к обсуждению интересного способа, которым Java делегирует ответственность за исключения.

Если отсутствует блок «попытка-перехват», который окружал бы утверждение throw внутри метода, из-за выброшенного исключения может показаться, что возврат метода происходит мгновенно. Больше никакие инструкции не выполняются и никакое значение не возвращается. В частности, в предыдущем примере ни один фрагмент кода, следующий за попыткой получить страницу из сети, не учитывает той проблемы, что предпосылка – страница была прочтена – не выполнена. Принято говорить, что метод был резко завершен, и в данном случае управление возвращается к getActions. Поскольку getActions также не содержит блок «попытка-перехват», он тоже резко завершается. Управление передается обратно (вверх по стеку) к вызывающей программе.

В данном случае при выбросе NetworkException управление возвращается к первому утверждению внутри блока перехвата (catch), приведенного в качестве примера. Это утверждение является инструкцией занесения сетевой ошибки в журнал. Принято говорить, что исключение было перехвачено первым утверждением catch, чей аргумент относится к тому же типу, что и тип выброшенного исключения, либо к супертипу этого исключения. Обработка возобновляется с первого утверждения в блоке перехвата и после этого продолжается в обычном режиме.

В данном случае сетевая ошибка, возникающая при попытке считать страницу из сети, вызовет резкое завершение как ReadPageFromNet, так и getPage. После того как блок перехвата запишет в журнал сообщение о неудаче, цикл for вновь попытается получить страницу, и так до достижения показателя MAXRETRIES.

Полезно иметь ясное представление о том, как организован корень дерева классов исключений в Java (рис. 2.1).

Все исключения являются подклассами Throwable. Практически не существует причин, по которым стоило бы ставить в коде ссылку на Throwable. Считайте его просто абстрактным базовым классом с двумя подклассами: Error и Exception. Error и его подклассы Предназначены для решения проблем, возникающих с самой средой времени исполнения Dalvik. Вы, конечно, можете написать код, который, казалось бы, сможет перехватывать Error (или Throwabl е), но на самом деле отлавливать их вы не сможете. В частности, очевидным доказательством этого является пример с ужасающим ООМЕ – так сокращенно называют ошибку OutOfMemoryException. Когда в системе Dalvik заканчивается память, она, возможно, не сможет завершить выполнение даже мельчайшего кода операции! Если вы напишете хитрый код, который попытается перехватить ООМЕ, а потом выделить определенный блок заранее зарезервированной памяти, это может сработать – или не сработать. Если вы пишете код, который пытается перехватить Throwable или Error, считайте, что вы таскаете воду решетом.

Рис. 2.1. Базовые классы исключений

Java требует, чтобы в сигнатуру метода входили исключения, которые этот метод может выбрасывать. В предыдущем примере getPage объявляет, что он выбрасывает три исключения, поскольку использует три метода, каждый из которых может выбросить одно. Методы, вызывающие getPage, должны, в свою очередь, объявлять все три исключения, выбрасываемые getPage, а также и все другие исключения, которые могут выбрасываться любыми другими методами, которые может вызывать getPage.

Как вы понимаете, эта ситуация оказывается обременительной для методов, расположенных достаточно высоко в дереве вызовов. Возможно, методу верхнего уровня потребуется объявить десятки видов самых разных исключений просто потому, что он вызывает методы, способные их выбрасывать. Для облегчения этой проблемы можно создать дерево исключений, конгруэнтное дереву приложения. Помните, что от метода требуется только объявлять супертипы для всех исключений, которые он выбрасывает. Если создать базовый класс под названием MyAppl іcationException, а потом сделать из него подклассы MyNetworkException и MyUI Exceptіon соответственно для подсистем, занятых работой с сетью и с пользовательским интерфейсом, то в коде верхнего уровня понадобится обрабатывать только МуАррlіcationException.

Но на самом деле это половинчатое решение. Предположим, выполнение сетевого кода не удается где-нибудь по пути к точке, расположенной глубоко в недрах приложения. Например, не удается установить сетевое соединение. Исключение продолжает выскакивать, несмотря на все повторные попытки и альтернативы. В какой-то момент оно становится совершенно размытым и сводится к тому, что «что-то пошло не так». Например, конкретное исключение базы данных не имеет никакого значения для кода, который пытается автоматически подставить набираемый телефонный номер. При добавлении исключения к сигнатуре метода именно на этом этапе возникает ситуация, которая попросту неудобна: вы можете и прямо объявить, что все ваши методы выбрасывают Exception.

Runt і meException – это особый подкласс Exception. К подклассам Runt і meException относятся непроверяемые исключения, которые не обязательно объявлять. Например, следующий код будет скомпилирован без ошибок:

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

Фреймворк коллекций Java

Фреймворк коллекций Java – это один из наиболее мощных и удобных инструментов этого языка. Он предоставляет объекты, которые являются коллекциями объектов: списки, наборы и карты. Все интерфейсы и реализации, составляющие эту библиотеку, находятся в пакете Java.uti 1.

В Java. uti 1 осталось несколько устаревших классов, которые можно считать реликтами. В сущности, они уже не относятся к фреймворку. Лучше их запомнить и стараться не использовать. Речь о классах Vector, Hashtable, Enumeration и Dictionary.

Источник: Android. Программирование на Java для нового поколения мобильных устройств

По теме:

  • Комментарии