русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Перспективы


Дата добавления: 2015-06-12; просмотров: 670; Нарушение авторских прав


Во-первых, язык Java, по сути, стал первопроходцем в использовании контролируемых исключений (несомненно из-за спецификаций исключений C++ и того факта, что программисты на C++ не уделяли им слишком много внимания). Это был эксперимент, повторить который с тех пор пока не решился еще ни один язык.

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

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

В прошлом я твердо считал, что для разработки надежных программ необходимы и контролируемые исключения, и строгая статическая проверка типов. Однако опыт, полученный лично и со стороны1, с языками, более динамичными, чем статичными, привел меня к мысли, что на самом деле главные преимущества обусловлены следующими аспектами:

· Унификация модели сообщения об ошибках посредством исключений (независимо от того, заставляет ли компилятор программиста их обрабатывать).



· Проверка типов, не привязанная к тому, когда она проводится — на стадии компиляции или во время работы программы.

Вдобавок снижение ограничений времени компиляции весьма положительно отражается на продуктивности программиста. С другой стороны, для компенсации чрезмерной жесткости статической проверки типов необходимы рефлексия и параметризация, как вы убедитесь в некоторых примерах книги. Некоторые уверяли меня, что все сказанное является кощунством, безнадежно испортит мою репутацию, приведет к гибели цивилизации и провалу большой доли программных проектов. Вера в то, что выявление ошибок на стадии компиляции спасет ваш проект, весьма сильна, но гораздо важнее сознавать ограничения того, на что способен компьютер. Стоит помнить: «Хороший язык программирования помогает программистам писать хорошие программы. Ни один из языков программирования не может запретить своим пользователям писать плохие программы». В любом случае исчезновение когда-либо из Java контролируемых исключений весьма маловероятно. Это слишком радикальное изменение языка, и защитники их в Sun весьма сильны. История Sun неотделима от политики абсолютной обратной совместимости — фактически любое программное обеспечение Sun работает на любом оборудовании Sun, как бы старо оно ни было. Но, если вы чувствуете, что контролируемые исключения становятся для вас препятствием (особенно если вас заставляют обрабатывать исключение, а вы не знаете, как с ним поступить), существует несколько вариантов.

 

Передача исключений на консоль

В несложных программах, как во многих примерах данной книги, простейшим решением является передача исключения за пределы метода main(), на консоль. К примеру, при открытии файла для чтения (подробности вы вскоре узнаете) необходимо открыть и закрыть потокFilelnputStream, который возбуждает исключения. В небольшой программе можно поступить следующим образом (подобный подход характерен для многих примеров книги):

//: exceptions/MainException.java

import java.io.*;

 

public class MainException {

// Передаем все исключения на консоль:

public static void main(String[] args) throws Exception {

// Открываем файл :

FileInputStream file =

new FileInputStream("MainException.java");

// Используем файл ...

// Закрываем файл:

file.close();

}

}

Заметьте, что main() — такой же метод, как и все прочие; он тоже может иметь спецификацию исключений, и здесь типом исключения является Exception, базовый класс всех контролируемых исключений. Передавая его на консоль, вы освобождаетесь от необходимости написания предложений try-catch в теле метода main().

 

Преобразование контролируемых исключений в неконтролируемые

Рассмотренный выше подход хорош при написании метода main(), но в более общих ситуациях не слишком полезен. Подлинная проблема возникает при написании тела самого обычного метода, когда при вызове другого метода вы четко сознаете: «Понятия не имею, что делать с исключением дальше, но „съедать" мне его не хочется, так же как и печатать банальное сообщение». Проблема решается при помощи цепочек исключений. Управляемое исключение просто «заворачивается» в класс RuntimeException примерно так:

try {

// ... делаем что-нибудь полезное

} саtch (НеЗнаюЧтоДелатьСЭтимКонтролируемымИсключением е) { throw new RuntimeException(e);

}

Решение идеально подходит для тех случаев, когда вы хотите «подавить» контролируемое исключение: вы не «съедаете» его, вам не приходится описывать его в своей спецификации исключений, и благодаря цепочке исключений вы не теряете информацию об исходном исключении.

Описанная методика позволяет игнорировать исключение и пустить его «всплывать» вверх по стеку вызова без необходимости писать блоки try-catch и (или) спецификации исключения. Впрочем, при этом вы все равно можете перехватить и обработать конкретное исключение, используя метод getCause(), как показано ниже:

//: exceptions/TurnOffChecking.java

// "Подавление" контролируемых исключений

import java.io.*;

import static net.mindview.util.Print.*;

 

class WrapCheckedException {

void throwRuntimeException(int type) {

try {

switch(type) {

case 0: throw new FileNotFoundException();

case 1: throw new IOException();

case 2: throw new RuntimeException("Where am I?");

default: return;

}

} catch(Exception e) { // Превращаем в неконтролируемое:

throw new RuntimeException(e);

}

}

}

 

class SomeOtherException extends Exception {}

 

public class TurnOffChecking {

public static void main(String[] args) {

WrapCheckedException wce = new WrapCheckedException();

// Можно вызвать throwRuntimeException() без блока try

// и позволить исключению RuntimeException покинуть метод:

wce.throwRuntimeException(3);

// Или перехватить исключение:

for(int i = 0; i < 4; i++)

try {

if(i < 3)

wce.throwRuntimeException(i);

Else

throw new SomeOtherException();

} catch(SomeOtherException e) {

print("SomeOtherException: " + e);

} catch(RuntimeException re) {

try {

throw re.getCause();

} catch(FileNotFoundException e) {

print("FileNotFoundException: " + e);

} catch(IOException e) {

print("IOException: " + e);

} catch(Throwable e) {

print("Throwable: " + e);

}

}

}

}

<spoiler text="Output:">

FileNotFoundException: java.io.FileNotFoundException

IOException: java.io.IOException

Throwable: java.lang.RuntimeException: Where am I?

SomeOtherException: SomeOtherException

</spoiler> Метод WrapCheckedException.throwRuntimeException() содержит код, генерирующий различные типы исключений. Они перехватываются и «заворачиваются» в объекты RuntimeException, становясь таким образом «причиной» этих ис­ключений. При взгляде на класс TurnOffChecking нетрудно заметить, что вызвать метод throwRuntimeException() можно и без блока try, поскольку он не возбуждает никаких контролируемых исключений. Но когда вы будете готовы перехватить исключение, у вас будет возможность перехватить любое из них — достаточно поместить свой код в блок try. Начинаете вы с перехвата исключений, которые, как вы знаете, могут явно возникнуть в коде блока try, — в нашем случае первым делом перехватывается SomeOtherException. В конце вы перехватываетеRuntimeException и заново возбуждаете исключение, являющееся его причиной (получая последнее методом getCause(), «завернутое» исключение). Так извлекаются из­начальные исключения, обрабатываемые в своих предложениях catch. Методика «заворачивания» управляемых исключений в объекты RuntimeException встречается в некоторых примерах книги. Другое возможное решение — создание собственного класса, производного от RuntimeException. Перехватывать такое исключение не обязательно, но, если вы захотите, такая возможность существует.

Основные правила обработки исключений

Используйте исключения для того, чтобы:

· обработать ошибку на текущем уровне (избегайте перехватывать исключения, если вы не знаете, как с ними поступить);

· исправить проблему и снова вызвать метод, возбудивший исключение;

· предпринять все необходимые действия и продолжить выполнение без повторного вызова метода;

· попытаться найти альтернативный результат вместо того, который должен был бы произвести вызванный метод;

· сделать все возможное в текущем контексте и заново возбудить это же исключение, перенаправив его на более высокий уровень;

· сделать все, что можно в текущем контексте, и возбудить новое исключение, перенаправив его на более высокий уровень;

· завершить работу программы;

· упростить программу (если используемая вами схема обработки исключений делает все только сложнее, значит, она никуда не годится);

· добавить вашей библиотеке и программе безопасности (сначала это поможет в отладке программы, а в дальнейшем окупится ее надежностью).

Резюме

Исключения являются неотъемлемой частью программирования на Java; существует некий барьер, который невозможно преодолеть без умения работать с ними. По этой причине исключения были представлены именно в этой части книги — многими библиотеками (скажем, библиотекой ввода/вывода) просто невозможно нормально пользоваться без обработки исключений. Одно из преимуществ обработки исключений состоит в том, что она позволяет сосредоточиться на решаемой проблеме, а затем обработать все ошибки в описанном коде в другом месте. Хотя исключения обычно описываются как средство передачи информации и восстановления после ошибок на стадии выполнения, я сильно сомневаюсь, что «восстановление» часто реализуется на практике. По моей оценке, это происходит не более чем в 10% случаев, и даже тогда в основном сводится к раскрутке стека к заведомо стабильному состоянию вместо реального выполнения действий по восстановлению. На мой взгляд, ценность исключений в основном обусловлена именно передачей информации. Java фактически настаивает, что программа должна сообщать обо всех ошибках в виде исключений, и именно это обстоятельство обеспечивает Java большое преимущество перед языками вроде C++, где программа может сообщать об ошибках разными способами (а то и не сообщать вовсе).


 



<== предыдущая лекция | следующая лекция ==>
Предыстория | Глава 13 ИНФОРМАЦИЯ О ТИПАХ


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 1.252 сек.