WebClub - Всероссийский Клуб Веб-разработчиков
WebClub.RU » Архив » Могущество исключений

Могущество исключений


Дата публикации: 17-03-2013

Использование исключений так широко применяется в программировании на Java, что они стали частью жизни. Из покон веков, прерывания обозначали ненормальное состояние, которое произошло во время работы программы. Но задумывались ли вы когда нибудть о том, что исключения могут так же помочь повысить скорость работы вашей программы, повысить производительность? Да, прерывания могут сделать это!

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

1. Программист не был обязан заботится об ошибочных ситуациях.
2. Если в программе и был код обработки ошибок, то он был смешан с обычным кодом (логикой программы), например:


// ...выполняемый код
if (read(fd, buf, 1024) < 0) {
/* Ошибка */
perror("Error while reading");
}
else {
// ...выполняемый код
}
// ...выполняемый код
Java достигла в использовании исключений таких же результатов. Например, если вы открываете файл, используя класс FileInputStream, вы должны позаботится о исключении FileNotFoundException в вашей программе. Так же вы должны поймать (catch) или передать (throw) его дальше. И тут нет выхода. Больше того, ваш код по обработке исключения находится отдельно от остального кода. При этом повышается читабельность исходного кода программы. Вы можете передать исключение дальше, что бы вызывающий мог обработать его самостоятельно. Таким образом, вы можете помещать исключения в стек исключений. При этом можно организовать общий код по обработке исключений, без использования дублирования. Например, вы можете выбрать для захвата все общие ошибки в вызывающем методе, таким образом исключая множественные обработки исключений в вызываемых методах.

Такие рассуждения - обычны при обсуждении исключений. Теперь же давайте взглянем на них под другим углом. Что может быть лучше кусочка кода? Давайте посмотрим.

/** Represents an employee. */
class Employee {

int id; // Employee's ID
String name; // Employee's name

/** Initializes an employee. */
Employee(int id, String name) {
this.id = id;
this.name = name;
}

/** Returns a string representation of the employee. */
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append(id);
buf.append(", ");
buf.append(name);
return buf.toString();
}

}

/** The list of employees. */
public class EmployeeList {

/** The default capacity. */
public final static int DEFAULT_CAPACITY = 2;

protected Employee[] list; // The employee list
protected int count; // The number of employees

/** Initialize the employee list. */
public EmployeeList() {
this.list = new Employee[DEFAULT_CAPACITY];
}

/**
* Adds an employee.
* This method leverages the use of exceptions to avoid "if"
* checks to increase the capacity of the list.
*/
public void addEmployee(Employee emp) {
try {
// Don't worry, add the element to the list
// If it exceeds the array size, an exception will
// be thrown
list[count++] = emp;
}
catch(ArrayIndexOutOfBoundsException e) {
// Need to increase the array's capacity
increaseCapacity();
// The count was incremented above
list[count - 1] = emp;
}
}

/** Increases the capacity of the list as needed. */
public void increaseCapacity() {
// Save the old list
Employee[] oldList = this.list;
// Create a new list
this.list = new Employee[list.length + DEFAULT_CAPACITY];
// Update the new list
System.arraycopy(oldList, 0, list, 0, oldList.length);
System.out.println("Increased capacity to " + list.length);
}

/** Prints the contents of the list. */
public void printList() {
for(int i = 0; i < count; i++) {
Employee emp = list[i];;
System.out.println(emp);
}
}

/** Main. */
public static void main(String[] args) {
// Initialize the employee list
EmployeeList el = new EmployeeList();
Employee emp1 = new Employee(1, "Issac Newton");
Employee emp2 = new Employee(2, "Albert Einstein");
el.addEmployee(emp1);
el.addEmployee(emp2);
el.printList();

// Add one more employee. This will demand an increase
// in the capacity since the index exceeds the array size.
Employee emp3 = new Employee(3, "Thomas Edison");
el.addEmployee(emp3);
el.printList();
}

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

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

Для дискуссии я использовал добавление в массив, но такая техника может быть применена и к другим операциям, например присвоение значений по умолчанию переменным при возникновении ошибочных ситуаций. Не забывайте, что такое использование исключений сугубо специально. Заметьте, что при этом возникают значительные накладные расходы связанные с подготовкой и обработкой исключений. Если в логике вашей программы такие расходы слишком высоки, то лучше использовать традиционный способ с использованием конструкции if. Так что перед использованием этой технологии убедитесь, что вы действительно поняли этот метод и проанализировали его подходимость к вашей программе.
Домен продается

Популярное

Не так давно в сети появился новый сервис, под названием Dead Man Zero. Этот сервис сделал...
Рынок социальных площадок уже давно стал стабильным. Несмотря на то, что время от времени...
Artisteer 4 – единственный в своем роде продукт, позволяющий автоматизировать работу над созданием...
Апрель 2024 (1)
Октябрь 2018 (14)
Февраль 2017 (3)
Январь 2017 (1)
Август 2016 (1)
Май 2016 (2)

Карта сайта: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41

Друзья сайта



Случайная цитата

Уоррен Баффет:

"Правило №1: Берегите деньги. Правило №2: Помните о правиле №1."

Опрос

Какой текстовый редактор Вы используете?

OpenOffice
AbiWord
Notepad++
UltraEdit
PSPad
Microsoft Office
Microsoft Блокнот
Другой...