بالنظر إلى هذا الرمز ، هل يمكنني أن أكون متأكدًا تمامًا من أن كتلة finally
تنفذ دائمًا ، بغض النظر عن something()
؟
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("I don't know if this will get printed out");
}
نعم ، سيتم استدعاء finally
بعد تنفيذ الكتل البرمجية try
أو catch
.
الأوقات الوحيدة التي لن يتم استدعاء finally
هي:
System.exit()
try
أو catch
kill -9 <pid>
على UNIXfinally
بواسطة خيط خفي وتنتهي كل مؤشرات الترابط غير الخفية قبل استدعاء finally
رمز المثال:
public static void main(String[] args) {
System.out.println(Test.test());
}
public static int test() {
try {
return 0;
}
finally {
System.out.println("finally trumps return.");
}
}
انتاج:
finally trumps return.
0
أيضًا ، على الرغم من أنها ممارسة سيئة ، إذا كان هناك بيان إرجاع داخل الكتلة النهائية ، فسيتم تجاوز أي عائد آخر من الكتلة العادية. وهذا يعني أن الكتلة التالية ستعود إلى خطأ:
try { return true; } finally { return false; }
نفس الشيء مع رمي استثناءات من الكتلة النهائية.
إليك الكلمات الرسمية من مواصفات لغة Java.
14.20.2. تنفيذ المحاولة - أخيرًا - تجربة المحاولة
يتم تنفيذ عبارة A
try
مع كتلةfinally
عن طريق تنفيذ الكتلةtry
أولاً. ثم هناك خيار:
- إذا تم تنفيذ كتلة
try
بشكل طبيعي ، [...]- إذا تم تنفيذ كتلة
try
فجأة بسببthrow
بقيمة V ، [...]- إذا تم تنفيذ حظر
try
فجأة لأي سبب آخر R ، فسيتم تنفيذ حظرfinally
. ثم هناك خيار:
- إذا اكتملت الكتلة أخيرًا بشكل طبيعي ، فسيتم إكمال عبارة
try
فجأة لسبب R.- إذا اكتملت كتلة
finally
فجأة لسبب S ، فسيتم إكمال عبارةtry
فجأة لسبب S (والسبب R هو المهملة).
مواصفات return
تجعل هذا الأمر صريحًا:
ReturnStatement: return Expression(opt) ;
عبارة
return
مع عدم وجودExpression
محاولات لنقل التحكم إلى invoker للطريقة أو المُنشئ الذي يحتوي عليها.عبارة
return
معExpression
محاولات لنقل التحكم إلى invoker للطريقة التي تحتوي عليها ؛ تصبح قيمةExpression
هي قيمة استدعاء الأسلوب.تقول الأوصاف السابقة "محاولات لنقل التحكم" بدلاً من "نقل التحكم" فقط إذا كانت هناك أي عبارات
try
ضمن الأسلوب أو المُنشئ الذي تحتوي كتلهtry
على عبارةreturn
، ثم سيتم تنفيذ أي جملfinally
من هذه العباراتtry
، بالترتيب ، من الأعمق إلى الأبعد ، قبل نقل السيطرة إلى المحتل للطريقة أو المُنشئ. يمكن أن يؤدي الإكمال المفاجئ لفقرةfinally
إلى تعطيل نقل عنصر التحكم الذي بدأته عبارةreturn
.
بالإضافة إلى الردود الأخرى ، من المهم الإشارة إلى أن "أخيرًا" لها الحق في تجاوز أي قيمة استثناء/تم إرجاعها بواسطة كتلة try..catch. على سبيل المثال ، ترجع التعليمة البرمجية التالية 12:
public static int getMonthsInYear() {
try {
return 10;
}
finally {
return 12;
}
}
وبالمثل ، فإن الطريقة التالية لا تلقي استثناء:
public static int getMonthsInYear() {
try {
throw new RuntimeException();
}
finally {
return 12;
}
}
في حين أن الطريقة التالية لا رميها:
public static int getMonthsInYear() {
try {
return 12;
}
finally {
throw new RuntimeException();
}
}
حاولت المثال أعلاه مع تعديل طفيف
public static void main(final String[] args) {
System.out.println(test());
}
public static int test() {
int i = 0;
try {
i = 2;
return i;
} finally {
i = 12;
System.out.println("finally trumps return.");
}
}
مخرجات الكود أعلاه:
يتفوق أخيرا العودة.
(2)
هذا لأنه عندما يتم تنفيذ return i;
i
له قيمة 2. بعد هذا يتم تنفيذ كتلة finally
حيث يتم تعيين 12 إلى i
ثم يتم System.out
الخروج.
بعد تنفيذ الكتلة finally
، ترجع الكتلة try
2 ، بدلاً من إرجاع 12 ، لأنه لم يتم تنفيذ جملة الإرجاع هذه مرة أخرى.
إذا كنت ستقوم بتصحيح هذا الرمز في Eclipse ، فستشعر أنه بعد تنفيذ System.out
من finally
، يتم تنفيذ جملة return
of try
مرة أخرى. ولكن هذا ليس هو الحال. تقوم ببساطة بإرجاع القيمة 2.
فيما يلي شرح إجابة كيفن . من المهم معرفة أن التعبير المراد إرجاعه يتم تقييمه قبل finally
، حتى إذا تم إرجاعه بعد.
public static void main(String[] args) {
System.out.println(Test.test());
}
public static int printX() {
System.out.println("X");
return 0;
}
public static int test() {
try {
return printX();
}
finally {
System.out.println("finally trumps return... sort of");
}
}
انتاج:
X
finally trumps return... sort of
0
هذه هي الفكرة الكاملة للكتلة أخيرًا. يتيح لك ذلك التأكد من قيامك بإجراء عمليات تنظيف قد يتم تخطيها لأنك تعود ، من بين أشياء أخرى ، بالطبع.
أخيرًا يتم استدعاء بغض النظر عما يحدث في كتلة المحاولة ( ما لم يمكنك استدعاء System.exit(int)
أو تشغيل Java Virtual Machine لسبب آخر).
طريقة منطقية للتفكير في هذا هي:
أخيرًا يتم تنفيذها دائمًا ما لم يكن هناك إنهاء غير طبيعي للبرنامج (مثل استدعاء System.exit (0) ..). لذلك ، سوف تحصل المطبوعة النظام الخاص بك
أيضا العودة في النهاية سوف يلقي أي استثناء. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html
يتم تنفيذ الحظر الأخير دائمًا ما لم يكن هناك إنهاء غير طبيعي للبرنامج ، إما بسبب تعطل JVM أو من مكالمة إلى System.exit(0)
.
علاوةً على ذلك ، فإن أي قيمة يتم إرجاعها من داخل الكتلة الأخيرة ستتجاوز القيمة التي تم إرجاعها قبل تنفيذ الكتلة الأخيرة ، لذا كن حذرًا من التحقق من جميع نقاط الخروج عند استخدام المحاولة أخيرًا.
لا ، ليست دائمًا حالة استثناء واحدة هي // System.exit (0)؛ قبل أن يمنع أخيرا كتلة ليتم تنفيذها.
class A {
public static void main(String args[]){
DataInputStream cin = new DataInputStream(System.in);
try{
int i=Integer.parseInt(cin.readLine());
}catch(ArithmeticException e){
}catch(Exception e){
System.exit(0);//Program terminates before executing finally block
}finally{
System.out.println("Won't be executed");
System.out.println("No error");
}
}
}
أخيرًا ما يتم تشغيله دائمًا وهذا هو بيت القصيد ، لمجرد أنه يظهر في الكود بعد الإرجاع لا يعني أنه كيف تم تطبيقه. يتحمل وقت تشغيل Java مسؤولية تشغيل هذا الرمز عند الخروج من الكتلة try
.
على سبيل المثال إذا كان لديك ما يلي:
int foo() {
try {
return 42;
}
finally {
System.out.println("done");
}
}
وقت التشغيل سيولد شيئًا كهذا:
int foo() {
int ret = 42;
System.out.println("done");
return 42;
}
إذا تم طرح استثناء غير معلوم ، فسيتم تشغيل الكتلة finally
وسيستمر نشر الاستثناء.
هذا لأنك قمت بتعيين قيمة i كـ 12 ، لكنك لم تُرجع قيمة i إلى الوظيفة. الرمز الصحيح هو كما يلي:
public static int test() {
int i = 0;
try {
return i;
} finally {
i = 12;
System.out.println("finally trumps return.");
return i;
}
}
لأنه سيتم دائمًا استدعاء كتلة أخيرًا إلا إذا قمت بالاتصال System.exit()
(أو تعطل السلسلة).
الجواب بسيطنعم.
إدخال:
try{
int divideByZeroException = 5 / 0;
} catch (Exception e){
System.out.println("catch");
return; // also tried with break; in switch-case, got same output
} finally {
System.out.println("finally");
}
انتاج:
catch
finally
نعم سوف تحصل على الاتصال. هذا هو بيت القصيد من وجود كلمة رئيسية في النهاية. إذا كان القفز خارج كتلة try/catch يمكن فقط تخطي الكتلة الأخيرة ، فسيكون ذلك هو وضع System.out.println خارج try/catch.
نعم ، وأخيرا يتم تنفيذ كتلة دائما. يستخدم معظم المطورين هذه الكتلة لإغلاق اتصال قاعدة البيانات ، وكائن مجموعة النتائج ، وكائن العبارة ، ويستخدم أيضًا في وضع الإسبات في Java لاستعادة المعاملة.
باختصار ، في وثائق Java الرسمية (انقر هنا ) ، تتم كتابة ذلك -
في حالة خروج JVM أثناء تنفيذ رمز try أو catch ، فقد لا يتم تنفيذ الحظر النهائي. وبالمثل ، في حالة مقاطعة مؤشر الترابط الذي ينفذ رمز try أو catch أو قتله ، فقد لا يتم تنفيذ الحظر النهائي على الرغم من استمرار التطبيق ككل.
نعم. الحالة الوحيدة لن يتم خروج JVM أو تعطلها
نعم. بغض النظر عن ما يحدث في كتلة المحاولة أو الالتقاط ما لم يكن System.exit () يُطلق عليه أو JVM معطلاً. إذا كان هناك أي بيان إرجاع في الكتلة (المجموعات) ، سيتم تنفيذ أخيرًا قبل بيان الإرجاع.
النظر في البرنامج التالي:
public class SomeTest {
private static StringBuilder sb = new StringBuilder();
public static void main(String args[]) {
System.out.println(someString());
System.out.println("---AGAIN---");
System.out.println(someString());
System.out.println("---PRINT THE RESULT---");
System.out.println(sb.toString());
}
private static String someString() {
try {
sb.append("-abc-");
return sb.toString();
} finally {
sb.append("xyz");
}
}
}
اعتبارًا من الإصدار 1.8.162 من Java ، توفر مجموعة التعليمات البرمجية أعلاه الإخراج التالي:
-abc-
---AGAIN---
-abc-xyz-abc-
---PRINT THE RESULT---
-abc-xyz-abc-xyz
هذا يعني أن استخدام finally
لتحرير الكائنات يعد ممارسة جيدة مثل التعليمات البرمجية التالية:
private static String someString() {
StringBuilder sb = new StringBuilder();
try {
sb.append("abc");
return sb.toString();
} finally {
sb = null; // Just an example, but you can close streams or DB connections this way.
}
}
حاولت هذا ، فمن الخيوط واحد.
class Test {
public static void main(String args[]) throws Exception {
Object obj = new Object();
try {
synchronized (obj) {
obj.wait();
System.out.println("after wait()");
}
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
}
سيكون الخيط الرئيسي في حالة الانتظار إلى الأبد ، وبالتالي لن يتم استدعاء
لذلك لن تتم طباعة إخراج وحدة التحكم السلسلة: after wait()
أو finally
متفق معStephen C ، المثال أعلاه هو واحد من الحالة الثالثة المذكورة هنا :
إضافة المزيد من هذه الاحتمالات حلقة لانهائية في التعليمات البرمجية التالية:
// import Java.util.concurrent.Semaphore;
class Test {
public static void main(String[] args) {
try {
// Thread.sleep(Long.MAX_VALUE);
// Thread.currentThread().join();
// new Semaphore(0).acquire();
// while (true){}
System.out.println("after sleep join semaphore exit infinite while loop");
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
}
الحالة 2: إذا تعطل JVM أولاً
import Sun.misc.Unsafe;
import Java.lang.reflect.Field;
class Test {
public static void main(String args[]) {
try {
unsafeMethod();
// Runtime.getRuntime().halt(123);
System.out.println("After Jvm Crash!");
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
private static void unsafeMethod() throws NoSuchFieldException, IllegalAccessException {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
unsafe.putAddress(0, 0);
}
}
المرجع: كيف تعطل JVM؟
الحالة 6: إذا تم تنفيذ الحظر نهائيًا بواسطة مؤشر ترابط daemon وسيتم إنهاء كافة مؤشرات الترابط غير daemon قبل يتم استدعاء وأخيراً.
class Test {
public static void main(String args[]) {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
printThreads("Daemon Thread printing");
// just to ensure this thread will live longer than main thread
Thread.sleep(10000);
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
};
Thread daemonThread = new Thread(runnable);
daemonThread.setDaemon(Boolean.TRUE);
daemonThread.setName("My Daemon Thread");
daemonThread.start();
printThreads("main Thread Printing");
}
private static synchronized void printThreads(String str) {
System.out.println(str);
int threadCount = 0;
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread t : threadSet) {
if (t.getThreadGroup() == Thread.currentThread().getThreadGroup()) {
System.out.println("Thread :" + t + ":" + "state:" + t.getState());
++threadCount;
}
}
System.out.println("Thread count started by Main thread:" + threadCount);
System.out.println("-------------------------------------------------");
}
}
الإخراج: هذا لا يطبع "أخيرًا" الذي يعني "أخيرًا كتلة" في "الخيط الخفي" لم يتم تنفيذ
main Thread Printing Thread :Thread[My Daemon Thread,5,main]:state:BLOCKED Thread :Thread[main,5,main]:state:RUNNABLE Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE Thread count started by Main thread:3 ------------------------------------------------- Daemon Thread printing Thread :Thread[My Daemon Thread,5,main]:state:RUNNABLE Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE Thread count started by Main thread:2 ------------------------------------------------- Process finished with exit code 0
نعم ، لأن لا يوجد بيان تحكم يمكن أن يمنع تنفيذ finally
.
فيما يلي مثال مرجعي ، حيث سيتم تنفيذ جميع مقاطع التعليمات البرمجية:
| x | Current result | Code
|---|----------------|------ - - -
| | |
| | | public static int finallyTest() {
| 3 | | int x = 3;
| | | try {
| | | try {
| 4 | | x++;
| 4 | return 4 | return x;
| | | } finally {
| 3 | | x--;
| 3 | throw | throw new RuntimeException("Ahh!");
| | | }
| | | } catch (RuntimeException e) {
| 4 | return 4 | return ++x;
| | | } finally {
| 3 | | x--;
| | | }
| | | }
| | |
|---|----------------|------ - - -
| | Result: 4 |
في البديل أدناه ، سيتم تخطي return x;
. النتيجة لا تزال 4
:
public static int finallyTest() {
int x = 3;
try {
try {
x++;
if (true) throw new RuntimeException("Ahh!");
return x; // skipped
} finally {
x--;
}
} catch (RuntimeException e) {
return ++x;
} finally {
x--;
}
}
المراجع ، بالطبع ، تتبع حالتها. يعرض هذا المثال مرجعًا مع value = 4
:
static class IntRef { public int value; }
public static IntRef finallyTest() {
IntRef x = new IntRef();
x.value = 3;
try {
return x;
} finally {
x.value++; // will be tracked even after return
}
}
finally
سيتم تنفيذه وهذا أمر مؤكد.
finally
لن يتم تنفيذه في الحالات التالية:
حالة 1 :
عندما تقوم بتنفيذ System.exit()
.
الحالة 2:
عندما تعطل JVM/الموضوع الخاص بك.
الحالة 3:
عندما يتم إيقاف التنفيذ الخاص بك بين يدويا.
try
- catch
- finally
هي الكلمات الأساسية لاستخدام حالة معالجة الاستثناء.
كما شرح طبيعي
try {
//code statements
//exception thrown here
//lines not reached if exception thrown
} catch (Exception e) {
//lines reached only when exception is thrown
} finally {
// always executed when the try block is exited
//independent of an exception thrown or not
}
وأخيرا منع كتلة تنفيذ ...
System.exit(0);
إذا لم تقم بمعالجة الاستثناء ، قبل إنهاء البرنامج ، ينفذ JVM الحظر أخيرًا. لن يتم تنفيذه إلا إذا فشل التنفيذ العادي للبرنامج في إنهاء البرنامج بسبب هذه الأسباب التالية ..
عن طريق التسبب في خطأ فادح يؤدي إلى إحباط العملية.
إنهاء البرنامج بسبب تلف الذاكرة.
عن طريق استدعاء System.exit ()
إذا ذهب البرنامج إلى حلقة اللانهاية.
هذا حقيقي في أي لغة ... أخيرًا ستنفذ دائمًا قبل بيان الإرجاع ، بغض النظر عن مكان الإرجاع في نص الأسلوب. إذا لم يكن الأمر كذلك ، فلن يكون للكتلة الأخيرة معنى كبير.
إضافة إلى @ vibhash 's الجواب كما لا توجد إجابة أخرى تشرح ما يحدث في حالة كائن قابل للتغيير مثل الكائن أدناه.
public static void main(String[] args) {
System.out.println(test().toString());
}
public static StringBuffer test() {
StringBuffer s = new StringBuffer();
try {
s.append("sb");
return s;
} finally {
s.append("updated ");
}
}
سوف الإخراج
sbupdated
نعم ، هو مكتوب هنا
في حالة خروج JVM أثناء تنفيذ رمز try أو catch ، فقد لا يتم تنفيذ الحظر النهائي. وبالمثل ، في حالة مقاطعة مؤشر الترابط الذي ينفذ رمز try أو catch أو قتله ، فقد لا يتم تنفيذ الحظر النهائي على الرغم من استمرار التطبيق ككل.
بالإضافة إلى النقطة المتعلقة بالإرجاع في النهاية استبدال العائد في كتلة المحاولة ، ينطبق الأمر نفسه على استثناء. أخيرًا ستحل الكتلة التي تطرح استثناءًا عن إرجاع أو استثناء يتم طرحه من داخل كتلة المحاولة.
توضح مواصفات Java Language كيف تعمل كتل try-catch-وأخيرا و try-catch في 14.20.2
في أي مكان ، تحدد أن الكتلة النهائية يتم تنفيذها دائمًا. ولكن بالنسبة لجميع الحالات التي تكتمل فيها كتل try-catch-وأخيرا و try-final ، فإنها تحدد أنه قبل التنفيذ يجب أن يتم تنفيذها.
try {
CODE inside the try block
}
finally {
FIN code inside finally block
}
NEXT code executed after the try-finally block (may be in a different method).
JLS لا تضمن أن يتم تنفيذ {FIN بعد CODE. تضمن JLS أنه إذا تم تنفيذ {CODE و NEXT فسيتم دائمًا تنفيذ {FIN بعد CODE وقبل (next _.
لماذا لا تضمن JLS أن يتم تنفيذ الكتلة النهائية دائمًا بعد كتلة المحاولة؟ لأنه مستحيل. من غير المحتمل ولكن من الممكن أن يتم إحباط JVM (القتل أو التعطل أو انقطاع التيار الكهربائي) مباشرةً بعد إكمال كتلة المحاولة ولكن قبل تنفيذ الحظر النهائي. لا يوجد شيء يمكن لـ JLS فعله لتجنب ذلك.
وبالتالي ، فإن أي برنامج يعتمد في سلوكه الصحيح على أخيرًا يتم تنفيذ الكتل دائمًا بعد أن يتم تجريب كتل المحاولات.
العوائد في كتلة المحاولة غير مرتبطة بهذه المشكلة. إذا وصل التنفيذ إلى التعليمات البرمجية بعد try-catch-وأخيراً ، فمن المؤكد أنه سيتم تنفيذ الحظر الأخير من قبل ، مع أو بدون إرجاع داخل كتلة try.
أخيرًا لن يتم استدعاء الكتلة بعد العودة في عدة سيناريوهات فريدة: إذا تم استدعاء System.exit () أولاً ، أو في حالة تعطل JVM.
اسمحوا لي أن أحاول الإجابة على سؤالك بأسهل طريقة ممكنة.
القاعدة 1 : يتم تشغيل الكتلة أخيرًا دائمًا (على الرغم من وجود استثناءات لها. ولكن دعونا نتمسك بهذا لبعض الوقت.)
القاعدة 2 : عبارات في تشغيل الكتلة أخيرًا عندما يترك عنصر التحكم تجربة أو كتلة catch. يمكن أن يحدث نقل التحكم كنتيجة للتنفيذ العادي أو لتنفيذ فترة راحة أو متابعة أو الانتقال إلى goto أو بيان الإرجاع ، أو لامتداد استثناء.
في حالة بيان الإرجاع على وجه التحديد (منذ التسمية التوضيحية) ، يجب أن يترك عنصر التحكم طريقة الاستدعاء ، وبالتالي يستدعي الكتلة النهائية لهيكل المحاولة المطابق. يتم تنفيذ بيان الإرجاع بعد الحظر الأخير.
في حالة وجود بيان عائد في المجموعة الأخيرة أيضًا ، فسوف يتجاوز بالتأكيد العبارة المعلقة في كتلة المحاولة ، نظرًا لأنه يزيل مكدس الاتصال.
يمكنك الرجوع إلى شرح أفضل هنا: http://msdn.Microsoft.com/en-us/ .... المفهوم هو نفسه في الغالب بجميع اللغات عالية المستوى.
نفسه مع الكود التالي:
static int f() {
while (true) {
try {
return 1;
} finally {
break;
}
}
return 2;
}
و سوف يعود 2!
لأنه يتم دائمًا استدعاء النهائي في أي حالة لديك. ليس لديك استثناء ، ما زال يطلق عليه ، استثناء catch ، لا يزال يسمى
نعم ، سيتم الاتصال دائمًا ولكن في حالة واحدة لا يتم الاتصال بها عند استخدام System.exit ()
try{
//risky code
}catch(Exception e){
//exception handling code
}
finally(){
//It always execute but before this block if there is any statement like System.exit(0); then this block not execute.
}
أخيرًا ، قم دائمًا بتنفيذ ما إذا كان مقبض الاستثناء أم لا. إذا حدث أي استثناء قبل محاولة المحاولة ، فلن يتم تنفيذ الحظر نهائيًا.
إذا تم طرح استثناء ، فسيتم تشغيله أخيرًا. إذا لم يتم طرح استثناء ، فسيتم تشغيله أخيرًا. إذا تم اكتشاف الاستثناء ، فسيتم تشغيله أخيرًا. إذا لم يتم اكتشاف الاستثناء ، فسيتم تشغيله أخيرًا.
المرة الوحيدة التي لا يعمل فيها هو عندما يخرج JVM.
ضع في اعتبارك هذا في سياق التنفيذ العادي (أي دون طرح أي استثناء): إذا لم تكن الطريقة "باطلة" ، فعادة ما تُرجع شيئًا بشكل صريح دائمًا ، ومع ذلك ، يتم دائمًا تنفيذ
جرب هذا الكود ، سوف تفهم الكود في النهاية يتم تنفيذ الكتلة بعد بيان الإرجاع .
public class TestTryCatchFinally {
static int x = 0;
public static void main(String[] args){
System.out.println(f1() );
System.out.println(f2() );
}
public static int f1(){
try{
x = 1;
return x;
}finally{
x = 2;
}
}
public static int f2(){
return x;
}
}
كنت في حيرة من أمري مع جميع الإجابات المقدمة في المنتديات المختلفة ، وقررت أخيرًا أن أشاهدها وشاهدها. و ouput هو:
في النهاية سيتم تنفيذها حتى لو كان هناك عودة في محاولة وقبض كتلة.
try {
System.out.println("try");
return;
//int i =5/0;
//System.exit(0 ) ;
} catch (Exception e) {
System.out.println("catch");
return;
//int i =5/0;
//System.exit(0 ) ;
} finally {
System.out.println("Print me FINALLY");
}
انتاج
محاولة
طباعة لي في النهاية
System.exit(0)
في محاولة وقبض كتلة في التعليمات البرمجية أعلاه ويحدث استثناء قبل ذلك ، لأي سبب من الأسباب.أخيرًا ، يمكن أيضًا الخروج قبل الأوان إذا تم طرح استثناء داخل كتلة أخيرة متداخلة. سوف يحذرك المحول البرمجي إلى أن الكتلة أخيرًا لا تكتمل بشكل طبيعي أو تعطي خطأ بأن لديك رمز يتعذر الوصول إليه. سيتم عرض خطأ التعليمات البرمجية التي يتعذر الوصول إليها فقط في حالة عدم وجود رمي خلف عبارة شرطية أو داخل حلقة.
try{
}finally{
try{
}finally{
//if(someCondition) --> no error because of unreachable code
throw new RunTimeException();
}
int a = 5;//unreachable code
}
وأخيرا يسمى دائما في النهاية
عند المحاولة ، يتم تنفيذ بعض التعليمات البرمجية ، إذا حدث شيء ما في المحاولة ، فحينئذٍ سيتم التقاط هذا الاستثناء ويمكنك طباعة بعض mssg أو رمي خطأ ، ثم يتم تنفيذ الحظر أخيرًا.
عادةً ما يتم استخدامه أخيرًا عند إجراء عمليات التنظيف ، على سبيل المثال ، إذا كنت تستخدم ماسح ضوئي في Java ، فيجب عليك إغلاق الماسح الضوئي لأنه يؤدي إلى مشاكل أخرى مثل عدم القدرة على فتح بعض الملفات
أخيرًا ، يتم تنفيذ حظر دائمًا حتى إذا وضعت عبارة إرجاع في كتلة المحاولة. سيتم تنفيذ الكتلة أخيرًا قبل بيان الإرجاع.