Biz indiyə kimi yazdığımız nümunələrdə ancaq bir try
ifadəsi işlətdik. Amma try
blokunun içində, eləcə də catch
və finally
bloklarının içində də digər bir try
ifadəsi işlədə bilərik:
import java.io.*; public class FileReaderExc { public static void main(String[] args) { FileReader reader = null; try { reader = read(); } catch (IOException e) { try { if (reader != null) { reader.close(); } } catch (IOException inner) { } } } private static FileReader read() throws IOException { // Code goes here #line1 } }
reader
obyekti ilə işimiz bitdikdən sonra onu bağlamalıyıq, bunun üçün close()
metodunu çağırırıq. close()
metodunun özü də IOException
fırladır və IOException
checked exception olduğundan onu da try-catch blokuna salıb handle edirik.
Əgər catch
və finally
bloklarının hər ikisində də exception fırladılarsa, fırladılan son exception olaraq finally blokundakı exception götürülür, catch blokundakı exception gizlədilir:
public static void test() { try { throw new RuntimeException(); } catch (Exception e) { throw new Exception(); } finally { throw new RuntimeException(); // the last exception } }
Bu metodu çağırsaq RuntimeException
baş verəcək. Əgər finally
blok olmasa, o zaman compiler fırladılan son exception olaraq sətir 24-ü qəbul edəcək və xəta verəcək. Çünki Exception
ckecked exception qrupuna aiddir, ona görə də ya handle olunmalıdır, ya da declare. Amma sətir 26-ya görə artıq sətir 24 unudulur və son exception olaraq RuntimeException
qəbul edilir.
Sonda qeyd etdiklərimizi yekunlaşdıraraq daha bir nümunəyə baxaq və metodun geriyə döndürdüyü dəyərə diqqət edək:
public String exceptions() { String result = ""; String v = null; try { try { result += "before "; v.length(); result += "after "; } catch (NullPointerException e) { result += "catch "; throw new RuntimeException(); } finally { result += "finally "; throw new Exception(); } } catch (Exception e) { result += "done "; } return result; }
Metodun geri döndürdüyü dəyər: before catch finally done
Daxildəki try
ifadəsinin fırlatdığı son exception (Exception
) checked exceptiondur və həmin try
ifadəsi digər bir try
ifadəsinin içində yazıldığından baş verən exception çöldəki (outer) try
ifadəsinin catch
blokunda tutulur, ona görə də kod compile olunur. Əgər sətir 45-də Exception
`u RuntimeException
etsək, sətir 43 compile olunmayacaq.
Bu kodla bağlı bəzi dəyişikliklər edib, qayıdan dəyərin necə dəyişəcəyinə diqqət yetirək:
- Əgər sətir 40 və 43-ü commentə salsaq, o zaman nəticə belə olacaqdır:
before catch finally
- Əgər sətir 40-ın əvəzinə
return result;
yazsaq və sətir 43-ü commentə salsaq, o zaman nəticə belə olacaqdır:before catch
Sırf bu nüansla bağlı bir nümunəni Exception mövzusunun əlavələrində qeyd etmişəm. Orada qeyd olunan linkdən bunun niyə belə baş verməsi ilə bağlı daha ətraflı məlumat ala bilərsiniz. - Əgər yalnız sətir 40-ın əvəzinə
return result;
yazsaq, o zaman nəticə belə olacaqdır:before catch finally done
Belə görünür ki, catch blokundareturn
ifadəsi işlədilsə dəfinally
blokunda yeni exception fırladılırsa, kodun axışı dəyişir,return
ifadəsi yazılmasına baxmayaraq nəzarət artıq daxildəkicatch
blokundan çıxır.