Грешки в
една
програма
могат да
бъдат
открити :
- по
време на
компилация
или
- по
време на
изпълнение
Езици като C обработват грешките като използват дума на състоянието, която трябва да бъде проверяване по време на изпълнението на програмата.
Този
подход крие
два риска:
- да
не се
проверяват
всички
възможни
грешки
- да
се обърне
програмата в
кошмар от
проверки
В обектно-ориентираното програмиране е избран един друг подход - обработка на изключения. Изключенията сменят последователността на изпълнение на инструкциите, при наличие на неочаквано събитие, обикновено грешка. В този случай управлението се предава на друга част от програмата, която прави опит да реагира адекватно на грешката.
Предимства
на подхода:
-
Не е
необходима
проверка на
всички
критични
точки в
програмата.
Всичко, което
трябва да се
направи е да се опише възможната реакция на програмата на специално
място на речено « exception handler» По
този начин може да се отдели кода на програмата от обработката на
възможните проблеми и да се направи по - четлива.
- Не е
необходимо
вземането на
решение в
текущия
контекст. В
този случай
може да се
генерира (throw)
изключение и
да се остави
решението на
друг
контекст от
програмата.
Няколко
понятия:
Действие |
Понятие |
Грешка по време на изпълнението на програмата |
|
Генериране на изключение |
|
Прихващане на изключение в друга част от програмата |
|
Програмния код за обработка на изключението |
|
Последователността от ``call statement`` , която завършва с метода където е генерирано изключението |
|
Няколко предефинирани изключения:
Exception
ClassNotFoundException
IllegalAccessException
InterrupredException
NoSuchMethodException
RuntimeException
ArithmeticException
ArrayStoreException
ClassCastException
NegativeArraysizeException
NullPointerException
SecurityException
IndexOutOfBoundsException
String IndexOutOfBoundsException
Array IndexOutOfBoundsException
IllegalArgumentException
NumberFormatException
IllegalThreadStateException
Генериране
на
изключение(Throwing)
Нека
обекта 'q' да
не е още
инициализиран.
Този факт
може да се
провери
преди
използването
на обекта и
обработката
на
ситуацията да
се остави на друг
контекст на
програмата:
if( q = = null)
throw new NullPointerException();
Възможно е генерирането на изключение посредством конструктор с един аргумент(низ от символи):
if(q == null)
throw new NullPointerException("q
= null");
Всички изключения имат по два конструктора - първият е подразбиращият се конструктор(без аргументи), а вторият е с един аргумент - низ от символи, който може да бъде анализиран в кода за обработка на изключението (exception handler ).
Когато в даден метод се генерира изключение се извършват следните действия :
В програмата могат да се въведат "проследявани" блокове:
try
{
//опасен
проследяван
код, който
може да
предизвика
изключение
}
catch(type1 id1) { // може
да има нула
или повече "catch"
блокове
//обработва
изключения
от тип "type1" в
проследявания
блок
}
catch(type2 id2) {
//обработва
изключения
от тип "type2"
}…
finally { //може
да има нула
или повече
"finally"
блокове
//изпълнява
се винаги,
независимо
дали има
изключение
или не
}
Обработващите блокове ("catch blocs") трябва да се намират непосредствено след « try » блока
Прекратяване или продължаване
Има два подхода в теорията на изключенията. Първият (възприет в Java) приема че изключенията представят сериозни грешки и изпълнението на програмата трябва да се прекрати. Следователно генерирането на изключение причинява обикновено прекратяването на засегнатия метод.
Вторият подход приема, че след обработката на изключението, може да се продължи изпълнението на метода ("resumption"). Вторият подход се реализира на Java чрез подходящо избран « try-catch » блок обхващащ кода където се появява грешката и ако трябва всичко може да се сложи в « while » клауза.
Прост
пример:
Сумиране на
две цели
числа- без
предвидено
изключение
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Sum extends JFrame { JTextField textField1,textField2,rez; JLabel l; int value1=0,value2=0,sum=0; Sum(){ setLayout(new FlowLayout()); textField1 = new JTextField(5); textField2 = new JTextField(5); textField1.addActionListener(new Enter()); textField2.addActionListener(new Enter()); l = new JLabel(" Type a number in each box!"); add(l); rez= new JTextField(18); add(textField1); add(textField2); add(rez); textField1.setText("0"); textField2.setText("0"); setSize(230,150); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } class Enter implements ActionListener { public void actionPerformed(ActionEvent e) { value1= Integer.parseInt(textField1.getText()); value2= Integer.parseInt(textField2.getText()); rez.setText(value1+value2+""); } } public static void main(String arg[]){ new Sum(); } } |
Сумиране
на две цели
числа -
изключението
е прихванато
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SumEx extends JFrame { JTextField textField1,textField2,rez; JLabel l; int value1=0,value2=0,sum=0; SumEx(){ setLayout(new FlowLayout()); textField1 = new JTextField(5); textField2 = new JTextField(5); textField1.addActionListener(new Enter()); textField2.addActionListener(new Enter()); l = new JLabel(" Type a number in each box!"); add(l); rez= new JTextField(18); add(textField1); add(textField2); add(rez); textField1.setText("0"); textField2.setText("0"); setSize(230,150); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } class Enter implements ActionListener { public void actionPerformed(ActionEvent e) { String rz=""; try{ value1= Integer.parseInt(textField1.getText()); value2= Integer.parseInt(textField2.getText()); rz=value1+value2+""; } catch(NumberFormatException ex){ rz="integers in each box please!"; } finally{ rez.setText(rz); } } } public static void main(String arg[]){ new SumEx(); } } |
Създаване
на собствени
изключения
Потребителят
може да
създава
собствени
изключения
чрез
наследяване
на
съществуващи.
Създаваните
изключения
трябва да
наследяват
най-близкия
по смисъл
клас. Ако има
колебание се
използва
директно
класът Exception.
class MyException extends
Exception {}
public class FinallyClause { |
MyException in "finally clause" No exception in finally clause" |
Собствено изключение - прихванато във функцията където възниква
class
NoNote extends Exception{ String message; NoNote(String message){ this.message = message; System.out.println(message); } } import java.util.*; public class Exc3 { static Scanner sc=new Scanner(System.in); public static void main(String arg[]){ System.out.println("Note: "+Note()); } static int Note(){ boolean ok; int note=200; do{ ok = true; System.out.print("next note:"); try{ String s= sc.nextLine(); note = Integer.parseInt(s); } catch(NumberFormatException ie){ System.out.println("Integer please!"); ok=false; continue; } try{ if((note>20)||(note <0)){ throw new NoNote("outside [0,20]"); } } catch(NoNote ex){ ok = false; } }while(!ok); return note; } } |
Собствено изключение - прихванато извън функцията където възниква
class
NoNote extends Exception{ String message; NoNote(String message){ this.message = message; System.out.println(message); } } import java.util.*; public class Exc4 { static Scanner sc=new Scanner(System.in); public static void main(String arg[]){ int note=0; //initialization boolean ok; do{ ok=true; try{ note = Note(); } catch(NoNote ex){ ok = false; } catch(NumberFormatException im){ ok=false; System.out.println ("Integer please"); } }while(!ok); System.out.println("Note: "+note); } static int Note() throws NoNote{ int note; System.out.print("next note:"); note = Integer.parseInt(sc.nextLine()); if((note>20)||(note <0)){ throw new NoNote("outside [0,20]"); } return note; } } |
class Bull extends Exception{ |
animals: animal: ADULT, FEMALE,herbivore:FAST animal: YOUNG, FEMALE,herbivore:FAST animal: ADULT, MALE,herbivore:SLOW animal: ADULT, MALE,herbivore:FAST animal: ADULT, FEMALE,herbivore:FAST animal: ADULT, FEMALE,herbivore:SLOW animal: ADULT, MALE wolf , starving:true animals: animal: ADULT, FEMALE,herbivore:FAST animal: YOUNG, FEMALE,herbivore:FAST animal: ADULT, MALE,herbivore:SLOW animal: ADULT, MALE,herbivore:FAST animal: ADULT, FEMALE,herbivore:FAST animal: ADULT, MALE wolf , starving:true animals: animal: ADULT, FEMALE,herbivore:FAST animal: YOUNG, FEMALE,herbivore:FAST animal: ADULT, MALE,herbivore:SLOW animal: ADULT, MALE,herbivore:FAST animal: ADULT, MALE wolf , starving:true BULL FOUND!! _____________________________ animals: animal: YOUNG,
MALE,herbivore:SLOW |