این exception جاوا catch نمیشود؟

بعد از اینکه با مبحث exception آشنا شدید زمان آن است که با یک معما آموختههای خود را بسنجید.
مثال زیر را در نظر بگیرید:
try { try { System.out.print("A"); throw new Exception("1"); } catch (Exception e) { System.out.print("B"); throw new Exception("2"); } finally { System.out.print("C"); throw new Exception("3"); } } catch (Exception e) { System.out.print(e.getMessage()); }
از نظر تئوری چه چیزی به نظرتان چاپ میکند؟ AB2C3؟
حال بیاییم آن را اجرا کنیم. نتیجه به این شکل است:
ABC3
عجیب نیست؟ exception(“2”) کجا رفت؟
این معما مساله خوبی است که فهم شما از try/catch/finally را میسنجد و در مصاحبهها نیز مورد استفاده قرار میگیرد.
طبق توضیحی که در Java Language Specification 14.20.2 آمده است داریم:
اگر یک بلوک catch به دلیل R به طور ناگهانی اجرای آن قطع شود، سپس بلوک finally اجرا میشود. در ادامه یک انتخاب وجود دارد:
- اگر بلوک finally به طور نرمال کامل شود، پس جمله try به دلیل R به طور ناگهانی اجرای آن قطع شده است.
- اگر بلوک finally به طور ناگهانی به دلیل S اجرای آن قطع شود، پس جمله try به طور ناگهانی به دلیل S قطع شده و دلیل R نادیده گرفته میشود.
پس در اینجا یک بلوک catch وجود دارد که یک خطا پرتاب میکند:
try { // ... } catch (Exception e) { throw new Exception("2"); }
اما یک بلوک finally وجود دارد که آن هم یک خطا پرتاب میکند.
finally { throw new Exception("3"); }
پس (“exception(“2 دور انداخته میشود و (“exception(“3 منتشر میشود.
این اتفاق برای returnای که در finally باشد هم برقرار است و return در بلوک finally هر return که در try یا catch وجود داشته باشد را بازنویسی (override ) میکند و به دلیل همین خاصیتهایی که گفته شد وجود return یا throw خطا در بلوک finally توصیه نمیشود.
منبع:
سلام لطفا کد ها رو واضع بنویسید ، اول باید کد رو مرتب کنم بعد بخونمش، خوب عمرا بیخیال می شم که کد رو بخونم 🙁
با تشکر
سلام
خیلی ممنون که اطلاع دادید. اصلاح شد.
در برخی از مطالب قدیمی ممکن است این مشکل وجود داشته باشد. اگر در مطالب دیگری هم این مشکل را مشاهده کردید، ممنون میشیم اطلاع بدید تا اصلاح کنیم.
This is really not always true as the following code never reach to the finally block.By the way., your comment area is not code friendly at all.
try {
System.out.println(“inside try”);
System.exit(1);
}finally{
System.out.println(“you never reach here!”);
}
ممنون از نظرتان.
اما مساله این است که بعد از فراخوانی متد exit هیچگاه return نمیشود و همینطور exceptionای نیز پرتاب نمیکند. به همین دلیل بلوک finally اجرا نمیشود.
طبق مستندات sun:
If the JVM exits while the try or catch code is being executed, then the finally block may not execute.
در اینجا هم طبق مستندات موجود در سایت اوراکل، گفته شده است که در صورتی که اجرای try/catch با وقفه انجام شود (به طور ناگهانی قطع شود یا همان compelete abruptly)
یا return در بلوک try/catch وجود داشته باشد چنین سناریویی رخ میدهد.