Мои Конспекты
Главная | Обратная связь


Автомобили
Астрономия
Биология
География
Дом и сад
Другие языки
Другое
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Металлургия
Механика
Образование
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Туризм
Физика
Философия
Финансы
Химия
Черчение
Экология
Экономика
Электроника

Проверяйте достоверность параметров



Большинство методов и конструкторов имеет ограничения на то, какие значения могут быть переданы с параметрами. Например, нередко указывается, что индексы должны быть неотрицательными, а ссылки на объекты отличны от null. Вы обязаны четко документировать все эти ограничения и начинать метод с их проверки. Это частный случай более общего принципа: стараться выявлять ошибки как можно cкоpee после того, как они произойдут. В противном случае обнаружение ошибки станет ме­нее вероятным, а определение источника ошибки - более трудоемким.

Если методу передано неверное значение параметра, но перед началом обработки он проверяет полученные параметры, то вызов этого метода быстро и аккуратно завер­шится с инициированием соответствующего исключения. Если же метод не проверяет своих параметров, может произойти несколько событий. Метод может завершиться посередине обработки, инициировав непонятное исключение. Хуже, если метод завер­шится нормально, без возражений вычислив неверный результат. Но самое худшее, если метод завершится нормально, но оставит некий объект в опасном состоянии, что впоследствии в непредсказуемый момент времени вызовет появление ошибки в какой-­либо другой части программы, никак не связанной с этим методом.

 

 

В открытых методах для описания исключений, которые будут инициироваться, когда значения параметров нарушают ограничения, используйте тег @throws генера­тора документации Javadoc (статья 44). Как правило, это будет исключение Illegal­ArgumentException, IndexOutOfBoundsException или NullPointe rException (статья 42). После того, как вы документировали ограничения для параметров метода и исключе­ния, которые будут инициироваться в случае нарушения ограничений, установить эти ограничения для метода не составит труда. Приведем типичный пример:

 

/**

* Возвращает объект Biglnteger, значением которого является

* (this mod m) Этот метод отличается от метода remainder тем,

* что всегда возвращает неотрицательное значение Biglnteger.

*

* @раrаm m - модуль, должен быть положительным числом * @return this mod m

* @throws ArithmeticException, если m <= О

*/

public Biglnteger mod(Biglnteger m) {

if (m.signum() <= О)

throw new ArithmeticException("Modulus not positive");

// Вычисления

 

Если метод не предоставляется в распоряжение пользователей, то вы как автор пакета контролируете все условия, при которых этот метод вызывается, а потому можете и обязаны убедиться в том, что ему будут передаваться только правильные значения параметра. Методы, не являющиеся открытыми, должны проверять свои параметры, используя утверждения (assertion), а не с помощью обычных проверок. В случае применения платформы Java, поддерживающей утверждения (версия 1.4 и выше), вы должны пользоваться конструкцией assert, в противном случае следует применять собственный механизм проверки утверждений.

Особенно важно проверять правильность параметров, которые не используются методом, а откладываются для обработки в дальнейшем. Например, рассмотрим стати­ческий метод генерации из статьи 16, который получает массив целых чисел и возвра­щает представление этого массива в виде экземпляра List. Если клиент метода передаст значение null, метод инициирует исключение NullPointerException, по­скольку содержит явную проверку. Если бы проверка отсутствовала, метод возвращал бы ссылку на вновь Сформированный экземпляр List, который будет инициировать исключение NullPointerException, как только клиент попытается им воспользоваться. К сожалению, к тому моменту определить происхождение экземпляра List будет уже трудно, что может значительно усложнить задачу отладки.

 

 

 

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

Существуют исключения из правила, обязывающего перед выполнением вычис­лений проверять параметры метода. Важное значение имеет ситуация, когда явная проверка является дорогостоящей или невыполнимой операцией, но вместе с тем параметры все же неявно проверяются непосредственно в процессе их обработки. Например, рассмотрим метод Collections.sort(List), сортирующий список объек­тов. Все" объекты в списке должны быть взаимно сравнимы. В ходе его сортировки каждый объект в нем будет сравниваться с каким-либо другим объектом из того же списка. Если объекты не будут взаимно сравнимы, в результате одного из таких сравнений будет инициировано исключение ClassCastException, а это именно то, что должен делать в таком случае метод sort. Таким образом, нет смысла выполнять упреждающую проверку взаимной сравнимости элементов в списке. Заметим, однако, что неразборчивое использование данного подхода может привести к потере такого качества, как атомарность сбоя (статья 46).

Иногда в ходе обработки неявно осуществляется требуемая проверка некоторых параметров, однако когда проверка фиксирует ошибку, инициируется совсем не то исключение. Другими словами, исключение, которое инициируется в ходе обработки и связано с обнаружением неверного значения параметра, не соответствует тому иск­лючению, которое, согласно вашему описанию, должно инициироваться этим методом. В таких случаях для преобразования внутреннего исключения в требуемое вы должны использовать ~диому трансляции исключении, описанную в статье 43.

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

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