Utisci korisnika

Zaista sam prijatno iznenađena vašom brigom za korisnike, i zahvaljujem vam se na maksimalnoj podršci. Što se tiče vaših usluga sve je jasno, ja se uvijek vraćam i nastaviću…

Želeo bih da Vam se zahvalim na Vašoj brzoj pošiljci, sertifikatu i novom kursu, koji sam juče preuzeo putem Post-expresa. Još jedanput Vam se zahvaljujem na Vašoj profesionalnosti.…


Kompletna lista utisaka

Testiranje online

Arhitektura računara

Za one koji žele da znaju više.

Windows OS

Ovo bi svakako trebalo da probate.

Odnosi s javnošću

Koliko znate PR?

Pogledajte još neke od testova

Newsletter

Ukoliko želite da Vas redovno obaveštavamo o novostima sa Link eLearning sajta prijavite se na našu newsletter listu.

Ime:

Prezime:

Email:


Anketa

Arhiva anketa

BAZA ZNANJA


Kurs: Core Windows Forms Technologies

Modul: Obrada izuzetaka

Autor: Marko Stojićević

Naziv jedinice: Izuzeci


Materijali vezani uz ovu lekciju:

- Test izuzeci
- Izuzeci (PDF dokument)



Pojam izuzetaka

Izuzetak je slučaj koji se dešava tokom izvršavanja programa koji može da poremeti normalan rad programa. Izuzetak može nastati zbog greške u kodu ili u kodu koji se poziva, usled neraspoloživosti resursa koji se poziva, nedostatka memorije, neočekivanih uslova pri izvršavanju koda, pogrešnog konvertovanja podataka, nepravilnih ulaznih podataka i sl. Izuzetak je objekat izveden iz klase Exception. Izuzeci se obrađuju korišćenjem ključnih reči try, catch i finally.


Obrada izuzetaka

Ovde je prikazan način obrade izuzetaka. Linije koda u kojima može doći do generisanja (izbacivanja) izuzetaka stavljaju se unutar try bloka.

try
{
     // deo koda u kome može doći do izuzetka
}

catch(Exception ex)
{
     // hendlovanje izuzetaka
}

Iza try bloka dolazi jedan ili više catch blokova koji kao što im samo ime kaže služe za hvatanje izuzetaka. U tom slučaju svaki catch blok hendluje specijalizovanu klasu izuzetaka. Kao što se vidi iza try bloka postavljen samo jedan catch blok. U prikazanom catch bloku hvataju se izuzeci tipa Exception. Pošto je svaka klasa izuzetaka izvedena iz ove klase izuzetaka ovakvim catch blokom biće uhvaćen bilo koji izuzetak. Ukoliko pri izvršavanju koda unutar try bloka ne dođe do generisanja izuzetaka kod unutar catch bloka se neće izvršavati. Kod unutar catch bloka naziva se exception handler. To može biti jednostavna poruka korisniku da je nepravilno uneo podatke u polja za unos. Bitno je da ne dođe do "pucanja" koda usled nepravilnosti u izvršavanju koda.

Primeri klasa izuzetaka

Ovde je prikazano hendlovanje izuzecima tipa NullReferenceException:

class MojaKlasa
{
     public int Vrednost;
}
try
{
     MojaKlasa  mojObjekat = new MojaKlasa ();
     mojObjekat = null;
     mojObjekat. Vrednost = 123;
}
catch( NullReferenceException)
{
     Conslole.WriteLine("Ne moze da se referencira null objekat");
}

Ovakav izuzetak se generiše pri referenciranju objekta koji ne postoji tj. null objekta. Klasa MojaKlasa je tzv. "umotani int" tj. ima samo jedan atribut tipa int. Unutar try bloka se instancira objekat ove klase. Referenca na ovaj objekat je mojObjekat. Zatim se referenci mojObjekat dodeljuje null vrednost što znači da sada mojObjekat ne referencira (ne ukazuje) ni na jedan objekat tj. to je null referenca. Kada se pokuša da se preko reference mojObjekat dodeli vrednost objektu na koji ta referenca ukazuje generiše se izuzetak tipa NullReferenceException tj. kompajler nas obaveštava da referenca ne ukazuje ni na kakav objekat. Treba rećia da postoje još neke od mnogobrojnih klasa izuzetaka kao što su IndexOutOfRangeException, izuzeci ove klase se generišu npr. kada pokušamo da pristupimo članu niza koji ne postoji. Treba napomenuti i klasu izuzetaka ArithmeticException čiji se objekti generišu usled nepravilnih aritmetičkih operacija, DividebByZeroException je klasa izuzetaka čiji se objekti generišu pri pokušaju deljenja sa nulo itd.


Korišćenje više catch blokova

Ukoliko se želi finija obrada izuzetaka koristi se više catch blokova. U zavisnosti od generisanog izuzetka se u tom slučaju primenjuje različit exception handler. U primeru prikazanom u nastavku se posebno obrađuju izuzeci tipa DivideByZeroException a posebno izuzeci tipa ArithmeticException. Posebno se vrši obrada izuzetaka ukoliko je došlo do deljenja sa nulom a posebno ukoliko je došlo do nekog drugog aritmetičkog izuzetka.

try
{
     // kod u kome dolazi do izuzetka
}
catch(DivideByZeroException )
{
     // kod se izvršava ukoliko dođe do pokušaja deljenja sa nulom
}
catch(ArithmeticException)
{
     // neki drugi aritmetički izuzetak npr. OverflowException
}

Prilikom pisanja više catch blokova moraju se najpre obrađivati izuzeci koji su specijalizovaniji a tek onda oni opštiji. Pošto je klasa DivideByZeroException izvedena iz klase ArithmeticException ukoliko bi redosled catch blokova bio obrnut nikada se ne bi ušlo u deo koda za obradu izuzetaka usled deljenja sa nulom jer je svaki takav izuzetak i aritmetički izuzetak.


Finally blok

Kada se izuzetak desi izvršavanje koda se zaustavlja i kontrola se predaje najbližem hendleru izuzetaka. To znači da se linije koda iza catch bloka ne izvršaju. Ukoliko se želi da se neki blok koda izvrši posle catch bloka (blokova) nezavisno od toga da li je došlo do izuzetka ili ne koristi se finally blok. Kod unutar finally bloka se izvršava nezavisno od toga da li je izuzetak generisan ili nije. U nastavku je prikazan tipičan primer korišćenja try, catch, finally strukture. Unutar try bloka se uspostavlja konekcija sa željenom bazom podataka. Takođe tu se izvršavaju operacije nad bazom podataka koje mogu da dovedu do generisanja izuzetaka, npr. narušavanje referencijalnog integriteta, unos pogrešnog tipa podataka, nedovoljan broj parametara i sl.
 
try
{
     // otvori konekciju
     // radi sa bazom
}
catch
{
     // catch exceptions
 }
finally

    // zatvori konekciju
}

Ukoliko je došlo do izuzetaka oni se hendluju unutar catch bloka. Bez obzira da li je došlo do izuzetaka ili nije potrebno je zatvoriti konekciju sa bazom podataka da bi se oslobodili njeni resursi. Zbog toga se zatvaranje konekcije vrši unutar finally bloka.


Eksplicitno izbacivanje izuzetaka

U nekim situacijama je potrebno da korisnik generiše izuzetak koji inače ne bi bio generisan od strane sistema. To je moguće uraditi korišćenjem ključne reči throw. Npr. izraz throw(new ArgumentNullException()) će generisati izuzetak ArgumentNullException. Ovakav izraz se mora napisati unutar try bloka ili unutar funkcije koja će biti pozvana unutar try bloka. Naravno i ovako generisani izuzetak se mora obraditi pisanjem catch blokova. Druga primena eksplicitnog izbacivanja izuzetaka je prikazana u primeru koji sledi. Sistemski generisan izuzetak se hvata unutar catch bloka, objektu izuzetka se dodaju neke informacije i izuzetak se ponovo izbacuje. Funkcija CitajPodatke() izbacuje ponovo prethodno uhvaćeni izuzetak.

private int CitajPodatke()
{
     byte brojMesta = 0 ; // 0 -255
     try
     {
          brojMesta = Convert.ToByte( textBroj.Text) ;
     }
     catch(FormatException ex)
     {
          // u catch bloku izbacujem novi izuzetak
          if(textBroj.Text.Length ==0)
          throw new FormatException("Unesite broj",ex);
          else
          throw ex ;
     }
     return brojMesta ;
}

 

Hendlovanje prethodno izbačenih izuzetaka

Funkcija iz prethodnog primera pod nazivom CitajPodatke() koja ponovo izbacuje prethodno uhvaćeni izuzetaka se poziva unutar try bloka. Pošto funkcija generiše izuzetak tipa FormatException , obrada izuzetaka se vrši za ovu klasu izuzetaka. Kada je izuzetak Y izbačen kao rezultat prethodno uhvaćenog izuzetka X tada Y. InnerExcePtion predstavlja referencu na izuzetak X. Dakle unutar catch bloka može se dobiti informacija o izuzetku koji je prethodno bio uhvaćen na prethodnom slajdu a zatim ponovo izbačen unutar try bloka.

try
{
     // funkcija koja usled izuzetka generiše novi izuzetak
     CitajPodatke();
}
catch(FormatException ex)
{
     MessageBox.Show(ex.Message);
     if(ex.InnerException != null)
     MessageBox.Show(ex.InnerException.Message);
}


Kreiranje sopstvenih klasa izuzetaka

Sve klase izuzetaka su izvedene iz klase System.Exception. Ova klasa ima property Mesasage pomoću koga se može iščitati poruka koja opisuje generisani izuzetak. Iz klase Exception su izvedene dve osnovne klase SystemException i ApplicationException. Klasa SystemException je bazna klasa za sve klase izuzetaka koje se odnose na sistem. Klasa ApplicationException je bazna klasa za sve klase izuzetaka koje se odnose na aplikaciju. Moguće je kreirati sopstvene klase izuzetaka izvodeći ih iz klase ApplicationException.

 

Primer kreiranja klase izuzetaka

Data je generisana korisnička klasa izuzetaka:

public class MojaKlasaIzuzetaka : ApplicationException
{
     private int broj ;

     public MojaKlasaIzuzetaka(int broj1)
     {
         broj = broj1 ;
     }

     public override string ToString()
     {
          return("Moj izuzetak broj  " + broj);
     }
}

U klasi je definisan celobrojni atribut pod nazivom broj. U klasi je takođe izvršeno prebrisavanje metode ToString koja konvertuje ulazni parametar metode u string. Kada se za objekat klase MojaKlasaIzuzetaka pozove metoda ToString ispisaće se poruka tipa Moj izuzetak broj M, gde je M vrednost atributa broj ove klase.

 

Primer funkcije koja generiše izuzetke

Data je funkcija koja izbacuje izuzetke korisnički definisane klase izuzetaka korišćenjem službene reči throw. Kada se funkciji prosledi kao ulazni parametar broj 1, 3 ili 5 ona izbacuje izuzetak u protivnom funkcija ne izbacuje izuzetak.


static void praviIzuzetak(int br)
{  
     switch(br)
     {
          case 1:
          case 3:
          case 5:
          throw new MojaKlasaIzuzetaka(br);
          break;
          default:
          Console.WriteLine("Nije napravljen izuzetak");
          break;
}

 

Testiranje sopstvene klase izuzetaka

Unutar try bloka se poziva funkcija koja generiše izuzetke korisnički definisane klase izuzetaka. Funkciji se kao ulazni parametar prosleđuje broj 5 da bi ona generisala izuzetak. Generisani izuzetak se hvata unutar catch bloka.

Na standardnom izlazu se dobija poruka Uhvacen izuzetak Moj izuzetak broj  5. Ovo je zbog činjenice da je metoda ToString prebrisana u izvedenoj klasi izuzetaka.

try
{
     praviIzuzetak(5);
}
catch(MojaKlasaIzuzetaka exc)
{
     Console.WriteLine("Uhvacen izuzetak " + exc.ToString());
}


Smatrate da je ova lekcija korisna?  Preporučite je. Broj preporuka:0


Molimo Vas unesite svoje podatke i dobićete pristup besplatnim lekcijama.

Ime: 
Prezime: 
Email: