• сделать все возможное в текущем контексте и заново возбудить
• сделать все, что можно в текущем контексте, и возбудить
• завершить работу программы;
• упростить программу (если используемая вами схема обработки исключений делает все только сложнее, значит, она никуда не годится);
• добавить вашей библиотеке и программе безопасности (сначала это поможет в отладке программы, а в дальнейшем окупится ее надежностью).
Резюме
Исключения являются неотъемлемой частью программирования на Java; существует некий барьер, который невозможно преодолеть без умения работать с ними. По этой причине исключения были представлены именно в этой части книги — многими библиотеками (скажем, библиотекой ввода/вывода) просто невозможно нормально пользоваться без обработки исключений.
Одно из преимуществ обработки исключений состоит в том, что она позволяет сосредоточиться на решаемой проблеме, а затем обработать все ошибки в описанном коде в другом месте. Хотя исключения обычно описываются как средство
Информация о типах
RTTI освобождает разработчика от необходимости выполнять всю работу с типами на стадии компиляции и открывает немало замечательных возможностей. Потребность в RTTI вскрывает целый ряд интересных (и зачастую сложных) аспектов объектно-ориентированного проектирования.
В этой главе рассматриваются способы получения информации об объектах и классах во время выполнения программы в Java. Существует два механизма получения такой информации: «традиционный» механизм RTTI, подразумевающий, что все типы доступны во время компиляции, а также механизм
Необходимость в динамическом определении типов (RTTI)
Рассмотрим хорошо знакомый пример с геометрическими фигурами, основанный на полиморфизме. Обобщенным базовым классом является фигура Shape, а производными классами — окружность Circle, прямоугольник Square и треугольник Triangle.
С04
г'
сО;
Это обычная диаграмма наследования — базовый класс расположен вверху, производные классы присоединяются к нему снизу. Обычно при разработке объектно-ориентированных программ код по возможности манипулирует ссылками на базовый класс (в нашем случае это фигура — Shape). Если вдруг в программу будет добавлен новый класс (например, производный от фигуры Shape ромб — Rhomboid), то код менять не придется. В нашем случае метод draw() класса является динамически связываемым, поэтому программист-клиент может вызывать этот метод, пользуясь ссылкой базового типа Shape. Метод draw() переопределяется во всех производных классах, и по природе динамического связывания вызов его по ссылке на базовый класс все равно даст необходимый результат. Это и есть полиморфизм.
Таким образом, обычно вы создаете объект конкретного класса (Circle, Square или Triangle), проводите восходящее преобразование к фигуре Shape («забывая» точный тип объекта) и используете ссылку на обобщенную фигуру. Реализация иерархии Shape может выглядеть примерно так:
//: typeinfo/Shapes java import java.util *;
abstract class Shape {
void drawO { System out. pri ntl n( this + ".drawO"), } abstract public String toStringO;
}
class Circle extends Shape {
public String toStringO { return "Circle"; }
}
class Square extends Shape {
public String toStringO { return "Square", }
}
class Triangle extends Shape {
public String toStringO { return "Triangle", }
}
public class Shapes {
public static void main(String[] args) {
List
new CircleO, new SquareO, new TriangleO
):
for(Shape shape . shapeList) shape. drawO;
}
} /* Output: Circle. drawO Square. drawO Triangle. drawO *///:-