Obrada izuzetaka
Šta je izuzetak?
Događaj koji se javlja u toku izvršenja programa i kvari normalno izvršenje.
Kada se desi izuzetak, sistem pokušava da pronađe način da ga obradi. Prosleđuje izuzetak, redom, metodima u
„call stack“ – u.
Primerimport java.util.Scanner;
public class ExceptionDemo {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("Enter an integer: ");int number = scanner.nextInt();scanner.close();
System.out.println("You've entered: " + number);}
}
PrimerEnter an integer:
4
You've entered: 4
Enter an integer:
A
Exception in thread "main" java.util.InputMismatchExceptionat java.util.Scanner.throwFor(Unknown Source)at java.util.Scanner.next(Unknown Source)at java.util.Scanner.nextInt(Unknown Source)at java.util.Scanner.nextInt(Unknown Source)at rs.ac.ni.pmf.marko.ExceptionDemo.main(ExceptionDemo.java:12)
Primerboolean success = false;do {try {
System.out.println("Enter an integer: ");int number = scanner.nextInt();System.out.println("You've entered: " + number);success = true;scanner.close();
} catch (InputMismatchException e) {System.out.println("Please enter an integer.");scanner.nextLine();
}
} while (!success);
Obrada izuzetka
Catch or Specify
Kod u kome može da se desi greška mora da zadovolji ipuni od dva zahteva Da implementira try naredbu koja „hvata“ i
obrađuje izuzetak Da specificira kakav izuzetak može da se
desi, korišćenjem throws naredbe Ukoliko ovo nije ispoštovano za
„checked“ izuzetke, kod se ne kompajlira
Vrste izuzetaka
Object
Throwable
Exception
RuntimeException ...
Error
...
Sistemske greške (Error)Er
ror
AssertionError
IOError
LinkageError
VirtualMachineError
...
Greške zbog spoljnih faktora (Runtime)
Run
timeE
xcep
tion NullPointerException
ArithmeticException
IndexOutOfBoundsException
IllegalArgumentException
...
Checked i Unchecked izuzeci
Error i RuntimeException su uncheckedizuzeci Prevodilac ne zahteva da se eksplicitno
obrađuju Ostali naslednici klase Exception su
checked izuzeci Prevodilac zahteva da budu ili obrađeni ili
bačeni iz metoda
try … catch … finally Kod koji može da proizvede grešku se
stavlja u try blok Izvršenje komandi u ovom bloku se prekida čim
dođe do izuzetka Izuzetak se obrađuje u catch bloku
Ukoliko catch blok ne obrađuje generisani izuzetak, on se prosleđuje dalje
Blok finally se uvek izvršava Služi za oslobađanje resursa i slične zadatke Počev od Java 7.0 postoji i try-with-resources
naredba
Primerpublic class ListOfNumbers {
private static final int SIZE = 10;private List<Integer> list;
public ListOfNumbers() {list = new ArrayList<Integer>();
for (int i = 0; i < SIZE; ++i) {list.add(i);
}}
public void writeList() {PrintWriter writer = new PrintWriter("numbers.txt");
for (int i = 0; i < SIZE; ++i) {writer.println("Value at " + i + " = " + list.get(i));
}
writer.close();}
public static void main(String[] args) {new ListOfNumbers().writeList();
}}
Primerpublic class ListOfNumbers {…
public void writeList() {try {
PrintWriter writer = new PrintWriter("numbers.txt");
for (int i = 0; i < SIZE; ++i) {writer.println("Value at " + i + " = " + list.get(i));
}
writer.close();} catch (FileNotFoundException e) {
…}
}}
Primerpublic class ListOfNumbers {…
public void writeList() {PrintWriter writer = null;try {writer = new PrintWriter("numbers.txt");
for (int i = 0; i < SIZE; ++i) {writer.println("Value at " + i + " = " + list.get(i));
}} catch (FileNotFoundException e) {…
} finally {if (writer != null) {writer.close();
}}
}}
Primerpublic class ListOfNumbers {…
public void writeList(String filename) {PrintWriter writer = null;try {writer = new PrintWriter(filename);
for (int i = 0; i < SIZE; ++i) {writer.println("Value at " + i + " = " + list.get(i));
}} catch (FileNotFoundException e) {…
} finally {if (writer != null) {writer.close();
}}
}}
throws naredba
Koristi se kada ne obrađujemo izuzetak u metodu u kome on može da nastane Često je potrebno samo prijaviti da je došlo
do izuzetka, a obradu prepustiti korisniku metoda
public void writeList(String filename)throws FileNotFoundException {PrintWriter writer = new PrintWriter(filename);
for (int i = 0; i < SIZE; ++i) {writer.println("Value at " + i + " = " + list.get(i));
}writer.close();
}
try - finallypublic void writeList(String filename) throws
FileNotFoundException {PrintWriter writer = null;
try {writer = new PrintWriter(filename);
for (int i = 0; i < SIZE; ++i) {writer.println("Value at " + i + " = " + list.get(i));
}} finally {
if (writer != null) {writer.close();
}}
}
catch blok
Može da bude više catch blokova koji hvataju različite izuzetke
Izuzetak se hvata prvim catch blokom koji odgovara
Od Java 7.0, moguće je u jednom catch bloku uhvatiti više tipova izuzetaka
Naredba throw
Služi da bi se eksplicitno bacio izuzetak na nekom mestu U slučaju da se izuzetak sam po sebi ne bi
desio, ali je potrebno prijaviti neki događaj u programu
U slučaju da je potrebno obraditi izuzetak, ali ga i proslediti pozivajućem metodu na dalju obradu
Ulančani izuzeci (Chained exceptions) Aplikacija često odgovara na izuzetak
bacanjem novog izuzetka Praktično, jedan izuzetak prouzrokuje drugi Zgodno je znati kada se ovo desi
Throwable to omogućava Throwable getCause() Throwable initCause() Throwable(String msg, Throwable cause)
Throwable(Throwable cause)
Pristup lancu izuzetakacatch (Exception cause) {
StackTraceElement elements[] = cause.getStackTrace();
for (int i = 0, n = elements.length; i < n; ++i) {
System.err.println(elements[i].getFileName()
+ ":"
+ elements[i].getLineNumber()
+ ">> "
+ elements[i].getMethodName() + "()");
}
}
}
Zadatak: Napraviti loger koji snima stack-trace kada se desi izuzetak.
Kreiranje sopstvenih izuzetaka
Nekada je potrebno obavestiti korisnika metoda da se desilo nešto nepredviđeno
Ukoliko već ne postoji odgovarajući izuzetak, treba napraviti novi Naslediti klasu Exception ili pogodnog
naslednika ove klase Implementirati odgovarajuće konstruktore
Iskoristiti throw za bacanje izuzetka