Wyjątki
Ziomal
Wyjątki pozwalają zachować kontrolę nad przebiegiem wykonania funkcji (metod), a także pojedynczych instrukcji zawartych w funkcjach. Wyjątek jest zdarzeniem, które pojawia się podczas wykonania i rozrywa normalną kolejność wykonania instrukcji.
W języku Java istnieje bardzo rozbudowana hierarchia (drzewo) predefiniowanych klas wyjątków, których superklasą jest klasa Throwable, a głównymi gałęziami drzewa są klasy Error i Exception. Część wyjątków należy do grupy tzw. wyjątków weryfikowalnych (checked exceptions): kompilator sprawdza, czy program zawiera procedury obsługi dla każdego wyjątku z tej grupy. Natomiast wyjątki klasy Error i jej podklas należą do grupy wyjątków nieweryfikowalnych (unchecked exceptions), ponieważ mogą one wystąpić w wielu punktach programu i powrót z nich jest trudny lub wręcz niemożliwy. Do grupy wyjątków nieweryfikowalnych należą też wyjątki klasy RuntimeException (podklasa Exception) i jej podklas, ponieważ zadeklarowanie w programie takich wyjątków nie mogłoby znacznie pomóc w ustaleniu (przez kompilator) poprawności programów.
Dla obsługi wyjątków weryfikowalnych wprowadzono cztery słowa kluczowe: throw, throws, try, catch i finally. Słowo kluczowe throw służy do jawnego zgłaszania wyjątków nieweryfikowalnych i występuje w instrukcji throw o składni throw wyrażenie;gdzie wyrażenie musi oznaczać zmienną lub wartość typu referencyjnego do klasy Throwable lub jej podklas. Zgłoszenie wyjątku w instrukcji throw spowoduje natychmiastowe opuszczenie bloku lub funkcji zawierającego instrukcję throw i znalezienie instrukcji try, która przechwyci zgłoszony wyjątek. Jeżeli nie ma takiej instrukcji try, zostanie wywołana metoda UncaughtException i wykonanie programu (lub wątku) zostanie zakończone.
Fraza:throws klasa_wyjątków
może wystąpić w nagłówku funkcji (metodzie wystąpienia, konstruktorze, funkcji klasy), np.
public staic void main(String args[]) throws Exception {/*...*/}
void printNumber(int number) throws WrongNumberException {/*...*/}
Fraza throws klasa_wyjątków oznacza, że dana funkcja może zgłaszać jedynie wyjątki podanej klasy.
Jeżeli wykonanie pewnej instrukcji programu może spowodować powstanie wyjątkowego zdarzenia, to musi ona być ujęta w blok instrukcji try, po którym muszą wystąpić procedury obsługi wyjątku mające postać frazy catch i bezpośrednio po catch (opcjonalnie) frazy finally. Składnia tej konstrukcji ma postać:
try {
/*....*/
}
catch(arg1 e1) {
/*....*/
}
catch(arg2 e2) {
/*....*/
} ... catch(argn en) {
/*....*/
} ... finally {
/*....*/
}
gdzie I oznacza instrukcje, arg1 .. argn to klasy wyjątków, e1 ... en to zmienne odniesienia do tych klas.
Blok catch należy traktować jako ciało procedury obsługi wyjątku należącego do klasy argi.
Jeżeli funkcja/metoda zawiera instrukcję try, to wyjątki mogą być zgłaszane wyłącznie w bloku try. Po zgłoszeniu wyjątku sterowanie opuszcza kod, który zgłosił wyjątek i przechodzi do pierwszej w kolejności procedury catch; jeżeli ta nie obsługuje wyjątku zgłoszonej klasy, jest on przekazywany do następnej. Blok frazy finally (jeśli występuje) jest wykonywany zawsze gdy kończy się wykonanie instrukcji try i to nawet wtedy, gdy wykonanie try zostaje gwałtownie przerwane.
Prosty program, który jedynie ilustruje składnię zgłaszania i obsługi wyjątków może wyglądać następująco:
import java.io.*;
public class TestEx {
public TestEx() {}
final int CONSTANT = 10;
void ff() throws IOException
{
try
{
System.out.println("I was here, within try statement.");
if(CONSTANT < 0)
throw new IOException("CONSTANT should be negative");
}
catch(IOException exc)
{
System.err.println("Caught IOException: "+ exc.getMessage());
}
finally
{
System.out.println("And now I am in finally blok");
}
}//end ff
public static void main(String args[]) throws IOException
{
TestEx te = new TestEx();
te.ff();
}//end main
}//end class
Podany niżej przykład definiuje klasę ListOfNumbers, wywołującą z pakietów Javy dwie metody klas, które mogą zgłosić wyjątki.
import java.io.*;
import java.util.Vector;
public class ListOfNumbers {
private Vector victor;
private static final int size = 10;
public ListOfNumbers () {
victor = new Vector(size);
for (int i = 0; i < size; i++)
victor.addElement(new Integer(i));
}
public void writeList() {
PrintWriter p = null;
try {
System.out.println("Entering try statement");
p = new PrintWriter(new FileOutputStream("OutFile.txt"));
for (int i = 0; i < size; i++)
p.println("Value at: " + i + " = " + victor.elementAt(i));
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("Caught ArrayIndexOutOfBoundsException: " +
e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} finally {
if (p != null) {
System.out.println("Closing PrintWriter");
p.close();
} else {
System.out.println("PrintWriter not open");
}
}
}
public static void main(String args[]) {
ListOfNumbers lst = new ListOfNumbers();
lst.writeList();
}//end main
}//end ListOfNumbers
Konstruktor ListOfNumbers() tworzy obiekt klasy Vector o dziesięciu elementach będących wartościami od 0 do 9. W klasie ListOfNumbers zdefiniowano także metodę writeList(), która zapisuje ten ciąg liczb do pliku tekstowego OutFile.txt. Metoda writeList() wywołuje dwie metody, które mogą zgłosić wyjątki:
konstruktor klasy FileOutputStream, który zgłasza IOException jeżeli z jakiegoś powodu nie może otworzyć pliku:
p = new PrintWriter(new FileOutputStream("OutFile.txt"));
metodę elementAt() klasy Vector, która zgłasza wyjątek ArrayIndexOutOfBoundsException jeżeli przekazana do niej wartość indeksu jest zbyt mała (liczba ujemna) lub zbyt duża (większa niż liczba elementów zawartych aktualnie w obiekcie klasy Vector).
Instrukcje System.err.println wykorzystują komunikaty generowane przez metodę getMessage klasy Throwable (lub jej podklasę), która podaje dodatkowe informacje o zaistniałym błędzie.
Jeżeli na dysku jest wystarczająco dużo miejsca na zapisanie pliku OutFile.txt, to program założy taki plik z zawartością:
Value at: 0 = 0
...
Value at 9 = 9
oraz wyprowadzi na ekran dwa wiersze tekstu:
Entering try statement
Closing PrintWriter
Artykuł pochodzi ze strony http://bsd.kam.pl/~swlasik/java/
zerżnięte! http://www.escom.net.pl/support/index632c.html?escom:JAVA
pokaż pozwolenie od autora, albo zarobisz bana
gdzie [delphi] ? ja tu nic nie widze..
poza tym odrobina formatowania - akapity, tagi < cpp>... co to ma być?
Zakladam, ze masz pozwolenie od autora na publikacje tego.