1. Giriş
Proqramlaşdırmada tez-tez elə vəziyyətlər olur ki, metod xətaya rast gəlir, amma onu düzgün necə emal edəcəyini bilmir. Məsələn, metod faylı oxuyur, amma fayl olmadıqda nə etməli olduğunu bilmir: istifadəçidən soruşmaq? Proqramı bitirmək? Başqa faylı sınamaq? Belə hallarda metod «məsuliyyəti ötürə» bilər — yəni istisnanı çağırışlar zənciri üzrə irəli «ötürə» bilər.
İstisnanın ötürülməsi — metodu xətanı özü emal etməməyə, əvəzində çağıran koda belə deməyə imkan verən mexanizmdir: «Burada problem var, özün həll et!»
Analoqiya: Təsəvvür edin, siz çağrı mərkəzinin əməkdaşısınız. Müştəri sizə cavabını bilmədiyiniz sualla zəng edir. Təxmin etmək əvəzinə deyirsiniz: «Bir dəqiqə, sizi mütəxəssisə qoşuram». Siz sualı irəli «ötürürsünüz».
Açar söz throws: necə işləyir
Java-da istisnaları ötürmək üçün metodun elanında throws açar sözü istifadə olunur.
Sintaksis:
tip_vozvrashchaemogo_znacheniya imyaMetoda(...) throws ExceptionType
{
// metodun kodu
}
throws-dan sonra həmin metodda yarana biləcək istisnanın tipi göstərilir. Bu, digər proqramçılar üçün xəbərdarlıq kimidir: «Diqqət! Bu metod belə tip istisna ata bilər. Hazır olun!»
Nümunə:
public void readFile(String filename) throws FileNotFoundException
{
FileReader reader = new FileReader(filename); // FileNotFoundException ata bilər
// ...
}
Burada readFile metodu xətanı özü emal etmir, əksinə bildirir: «Mən FileNotFoundException ata bilərəm — qoy məni çağıran qərar versin, nə etsin».
2. Çağıran metod necə reaksiya verməlidir?
Əgər siz throws ilə elan edilmiş metodu çağırırsınızsa, iki variantınız var:
- İstisnanı try-catch vasitəsilə emal etmək
- İstisnanı yenə də irəli ötürmək (öz metodunuza throws əlavə etmək)
Variant 1: try-catch vasitəsilə emal etmək
public static void main(String[] args)
{
try
{
readFile("data.txt");
}
catch (FileNotFoundException e)
{
System.out.println("Fayl tapılmadı: " + e.getMessage());
}
}
Burada istisnanı tutur və nə edəcəyimizi özümüz qərar veririk (məsələn, istifadəçiyə mesaj göstəririk).
Variant 2: irəli ötürmək
public static void main(String[] args) throws FileNotFoundException
{
readFile("data.txt");
}
İndi xətanın emal edilməsi üçün məsuliyyət main-i çağıran tərəfin üzərinə düşür (adətən bu, elə JVM-dir — əgər xəta emal olunmasa, proqram səhv mesajı ilə dayanar).
3. Nümunə: istisnanı ötürmə ilə faylın oxunması
IOException ilə və emalın main səviyyəsində aparılması ilə tam nümunə:
import java.io.*;
public class FileDemo
{
// Metod IOException ata biləcəyini elan edir
public static void printFirstLine(String filename) throws IOException
{
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line = reader.readLine();
System.out.println("İlk sətir: " + line);
reader.close();
}
public static void main(String[] args)
{
try
{
printFirstLine("nofile.txt");
}
catch (IOException e)
{
System.out.println("Faylı oxuyarkən xəta: " + e.getMessage());
}
}
}
printFirstLine metodu fayl olmadıqda nə etməli olduğunu bilmir — o, sadəcə istisnanı ötürür. main-də xətanı tutur və mesajı çıxarırıq.
4. Faydalı nüanslar
İstisnaların ötürülməsini nə vaxt və niyə istifadə etməli?
- Metod xətanı necə emal etməli olduğunu ya bacarmadıqda, ya da buna ehtiyac olmadıqda (məsələn, kitabxana kodu).
- Xəta emalı kontekstdən asılı olduqda (bir halda proqramı bitirmək, başqa halda isə başqa faylı yoxlamaq).
- Gərək olmayan yerdə artıq try-catch blokları ilə kodu «çirkləndirməmək» üçün.
Ən yaxşı təcrübə: Mənalı şəkildə emal edə bilmirsinizsə, istisnaları ötürün. Sadəcə formal olaraq istisnaları tutmayın!
Bir neçə istisnanı da ötürmək olar
public void process() throws IOException, SQLException
{
// ...
}
Checked və unchecked istisnalar: xatırlatma
Checked exceptions (məsələn, IOException, SQLException) — kompilyator onların emalını və ya ötürülməsini tələb edir.
Unchecked exceptions (məsələn, NullPointerException, IllegalArgumentException) — kompilyator emalı tələb etmir, onları throws-da göstərməyə ehtiyac yoxdur.
5. İstisnaları ötürərkən tipik səhvlər
Xəta № 1: checked istisna üçün throws elan etməyi unutmusunuz.
Əgər metod checked istisna ata bilərsə, amma siz onu throws-da elan etməmisiniz və try-catch ilə emal etməmisinizsə — kompilyator xəta verəcək.
Xəta № 2: istisnanı tutursunuz, amma onu emal etmirsiniz.
catch (Exception e) {} yazmaq — pis təcrübədir! Nə edəcəyinizi bilmirsinizsə, istisnanı irəli ötürmək daha yaxşıdır.
Xəta № 3: həddən artıq ümumi tipi ötürürsünüz.
Əgər metod yalnız FileNotFoundException ata bilirsə, throws Exception yazmayın — bu, kodun başa düşülməsini çətinləşdirir.
Xəta № 4: unchecked istisnaları throws-da göstərirsiniz.
throws NullPointerException yazmağın mənası yoxdur — bunu kompilyator tələb etmir və bu, xəta emalına kömək etmir.
GO TO FULL VERSION