Когато е изхвърлено съобщение системата, обслужваща изключенията преглежда “на-близките” обработчици в реда, в който са написани. Когато намери съвпадение, изключението се счита уредено, по-нататъшно търдене не се прави.
Съвпадането не изиксва точно съответствие между изключението и обработчика. Обект от извлечен клас ще стане за обработчик предназначен за базовия клас, както е показано в примера:
//: c09:Human.java
// Catching Exception Hierarchies
class Annoyance extends Exception {}
class Sneeze extends Annoyance {}
public class Human {
public static void main(String[] args) {
try {
throw new Sneeze();
} catch(Sneeze s) {
System.out.println("Caught Sneeze");
} catch(Annoyance a) {
System.out.println("Caught Annoyance");
}
}
} ///:~
Изключението Sneeze ще се хване в първата catch клауза за която става, като това е първата такава, разбира се. Ако обаче махнете първата клауза:
try {
throw new Sneeze();
} catch(Annoyance a) {
System.out.println("Caught Annoyance");
}
Оставащата ще действа, понеже ще хване базовия клас на Sneeze. С други думи, catch(Annoyance e) ще хване Annoyance и всеки клас извлечен от него. Това е полезно понеже ако решите да добавите изключения към някой метод, ако те са наследени от същия базов клас, клиентският код няма да изисква промяна, като се предполага, че той хваща базовия клас, най-малкото.
Ако се опитате да “маскирате” изключенията на извлечения клас чрез слагане на клаузата на базовия клас първа, както тук:
try {
throw new Sneeze();
} catch(Annoyance a) {
System.out.println("Caught Annoyance");
} catch(Sneeze s) {
System.out.println("Caught Sneeze");
}
компилаторът ще издаде съобщение за грешка, понеже вижда че catch-клаузата на Sneeze не може никога да бъде достигната.
Правила за изключенията
Използвайте изключенията за да:
-
Оправите проблема и извикате четода (който е предизвикал изключението) пак.
-
Закърпите нещата и продължите без да викате метода пак.
-
Получите резултат, различен от този който се получава по обичайния начин.
-
Направите каквото може в този контекст и преизхвърлите същото изключение към по-висок контекст.
-
Направите каквото може в този контекст и изхвърлите друго изключение към по-високия контекст.
-
Прекратите програмата.
-
Опростите. Ако вашата ссхема на изключения усложнява нещата, тя е болезнена и вбесяваща при използване.
-
Направите библиотеката и програмата си по-сигурни. Това е краткосрочна инвестиция (за тестването) и дългосрочна (за готовата програма).
Резюме
Развитото възстановяване след грешки е един от най-мощните начини да се повиши качеството на програмите. Възстановяването от грешки е основно за всяка програма която пишете, а е особено важно в Java, където основна дейност е да се създават части от програми за използване от други хора. За да се създаде качествена система всеки компонент трябва да бъде качествен.
Целите на поддръжката на изключения в Java са да се опрости създаването на големи, надеждни програми чрез писане на по-малко код отколкото в момента е възможно, с по-голяма увереност, че вашата програма няма да допусне грешка, от която няма да се възстанови.
Изключенията не са ужасяващо трудни за научаване, те са една от онези черти, които дават непосредствени и значителни ползи за вашия проект. За щастие Java налага всички аспекти така че те ще бъдат смислено използвани както от проектанта на библиотеката, така и от клиента-програмист.
Упражнения -
Създайте клас в main( ) който изхвърля обект от клас Exception вътре в try блок. Дайте на конструктора на Exception стрингов аргумент. Хванете изключението вътре в catch клауза и изведете стринговия аргумент. Добавете клауза finally и изведете съобщение за да докажете че сте били там.
-
Създайте ваш собствен клас-изключение чрез ключовата дума extends. Напишете конструктор за този клас който взема String аргумент и го запомня вътре в обекта чрез String манипулатор. Напишете метод който извежда запомнения String. създайте try-catch клауза за изпитание на новото ви изключение.
-
Напишете клас с метод, който изхвърля изключението от упражнение 2. Опитайте да го компилирате без спецификация на изключенията за да видите какво ще каже компилаторът. Добавете подходяща спецификация на изключението. Изпробвайте вашият клас и изклчението в try-catch клауза.
-
Намерете в глава 5 двете програми наречени Assert.java и ги променете да изхварлят собствени изключения наместо да пишат чрез System.err. Изключението да бъде вътрешен клас който разширява RuntimeException.
10: Входно-изходна система на Java
Създаването на добра входно/изходна (IO) система е една от по-трудните задачи на проектанта на езика.
Това се вижда от брая на различните подходи. Прадизвикателството каточели е да се покрият всички възможности. Не само че има различни видове вход/изход (IO) с които искате да комуникирате (файлове, конзолата, мрежови връзки), но искате да им говорите по най-разнообразни начини (последователно, с произволен достъп, двоично, знаково, на редове, на думи и т.н.).
Проектантите на библиотеките на Java атакуваха проблема чрез създаване на множество класове. Фактически има толкова много класове в IO системата на Java че може да се уплашите в началото (иронично, дизайнът на Java IO фактически предотвратява експлозията на класовете). Има също значителна промяна в библиотаките IO между Java 1.0 и Java 1.1. Вместо просто да заместят старата библиотека с нова, проектантите в Sun разшириха старата и добавиха успоредно с нея и нова. Като резултат мож понякога да смесвате старата и новата библиотека и да създавате още по-плашещ код.
Тази глава ще ви помогне да разберете разнообразните IO в стандартната библиотека на Java и как да ги използвате. Първата част на главата ще ви запознае със “старата” потокова IO библиотека на Java 1.0, понеже има значително количество съществуващ код, който я използва. Останалата част на главата разглежда новите черти на IO библиотеката на Java 1.1. Забележете че когато компилирате нещо от първата част на главата с компилатор за Java 1.1 може да получите съобщение-предупреждение “deprecated feature” по време на компилация. Кодът си работи; компилаторът просто ви съветва да използвате някои нови черти, описани във втората част на главата. Ценно е, обаче, да се види разликата между двете библиотеки чрез правене на неща по двата начина и това е причината първата част на главата да остане – за да повиши разбирането (и за да ви позволи да четете код написан за Java 1.0).
Сподели с приятели: |