متى يجب استخدام Throwable بدلاً من الاستثناء الجديد؟
سؤال
منح: Throwable
يكون Exception
الطبقة المتفوقة.
عندما أقرأ نصوصًا عن كتابة "الاستثناءات" الخاصة بك، أرى أمثلة عليها Throwable
المستخدمة في catch
تظهر الكتلة والنصوص الأخرى new Exception()
المستخدمة في catch
حاجز.لم أر بعد شرحًا للوقت الذي يجب فيه استخدام كل منهما.
سؤالي هو هذا، متى ينبغي ذلك Throwable
استخدامها ومتى ينبغي new Exception()
يستخدم؟
داخل catch
أو else
الحظر باستخدام إما:
throw throwable;
أو
throw new Exception();
المحلول
و(من تعليق) المشكلة التي جلبت هذا الأمر هو أن ولست بحاجة لتمرير "استثناء" ل قطعة من رمز هو بناء زميل العمل إذا كان جمع لا يحصل بناؤها.
اقتباس فقرة> في هذه الحالة، قد ترغب في رمي <م> تحديد استثناء م>. هل يمكن رمي Exception
، وهو مناسب الحالية فرعية منه (باستثناء RuntimeException
والفئات الفرعية التي هي <م> لحالها م>)، أو فئة فرعية مخصصة من Exception
(على سبيل المثال "CollectionBuildException
"). انظر جافا البرنامج التعليمي على الاستثناءات للحصول على ما يصل الى سرعة مع استثناءات جافا.
نصائح أخرى
ورمي دائما على Exception
(أبدا Throwable
). أنت عموما لا يمسك Throwable
سواء، ولكن يمكنك. قابل للظهور هي المتفوقة لException
وError
، لذلك كنت قبض Throwable
إذا أردت أن يمسك Exception
s لكن Error
s ليس فقط، وهذا هو بيت القصيد في وجود لها. الشيء هو، Error
s عادة ما تكون الأشياء التي من شأنها ولا ينبغي قبض على التطبيق العادي، لذلك مجرد استخدام Exception
لم يكن لديك سبب محدد لاستخدام Throwable
.
ويجب أن لا يمسك حقا استثناء ورمي واحد جديد في عام باسم "استثناء الجديد".
وبدلا من ذلك، إذا كنت ترغب في فقاعة يصل باستثناء تفعل ما يلي:
try {
// Do some stuff here
}
catch (DivideByZeroException e) {
System.out.println("Can't divide by Zero!");
}
catch (IndexOutOfRangeException e) {
// catch the exception
System.out.println("No matching element found.");
}
catch (Throwable e) {
throw e; // rethrow the exception/error that occurred
}
وليس من الممارسات الجيدة، على ما أعتقد، لجذب استثناء ورمي استثناء جديد بدلا من تلك التي أثيرت في كتلة التعليمات البرمجية الخاصة بك، إلا إذا رفع استثناء مخصصة مفيد يوفر السياق يكفي أن يتملص من أجل قضية باستثناء الأصلي.
ومكانين فقط سترى Throwable
كلمة في التعليمات البرمجية:
public static void main(String args[])
{
try
{
// Do some stuff
}
catch(Throwable t)
{
}
}
و
public class SomeServlet extends HttpServlet
{
public void doPost(HttpRequest request, HttpResponse response)
{
try
{
// Do some stuff
}
catch (Throwable t)
{
// Log
}
}
}
<الإضراب> قابل للظهور هي واجهة، وليس فئة. إضراب> فئتين تمتد قابل للظهور، واستثناء خطأ.
والقاعدة هي: أن تكون محددة كما يمكنك عند اصطياد استثناءات - وهذا يعني على سبيل المثال اصطياد استثناء بدلا من قابل للظهور، وIOException بدلا من استثناء
.ولا يمسك أخطاء - الأخطاء هي أخطاء. إصلاح رمز بدلا من ذلك.
إذا كان لديك للقبض على كل شيء، استخدم "قبض قابل للظهور"، ولكن هذا هو شكل سيء.
وthrow new Exception();
شيء يجب عليك <م> لا م> القيام به في كتلة الصيد، ولكن قد تضطر إلى أو تريد أن تفعل new SomeException(throwable);
رمي (الحفاظ على تتبع مكدس الكامل) بدلا من throw throwable;
لتتوافق مع API طريقة الخاص بك، على سبيل المثال عندما يعلن لرمي SomeException
ولكن كنت استدعاء التعليمات البرمجية التي قد رمي IOException
أن كنت لا تريد أن تضيف إلى بند throws
لك طريقة ل.
وهذه القضية ربما الأكثر شيوعا هو new RuntimeException(throwable);
لتجنب وجود بند throws
تماما. كثير من الناس سوف اقول لكم هذا الاعتداء الرهيب لأنك يجب أن يكون استخدام التحقق من الاستثناءات. IMO أنهم مخطئون ودققت الاستثناءات وخطأ في تصميم لغة جافا التي تنتج فقط في القبيح، رمز غير قابل للدعم.
وكما سمعت أنه عندما جاءت جافا لأول مرة، كانت النظرية التي قابل للظهور يمكن استخدامها لنقل السيطرة في حالات أخرى إلى جانب الاستثناءات. أنا لم أر قط استخدامه بهذه الطريقة على الرغم من (وربما كان هذا شيء جيد جدا).
وحتى مجرد التقاط استثناء (أو الأفضل من ذلك، استثناء أكثر غرامة الحبيبات).
والمقصود قابل للظهور ليتم القبض إلا من خلال هذه الحاوية أو حلقة رئيسية من البرنامج. أكثر من مرة اصطياد الاشياء دون استثناء مثل خطأ لا يضيف الكثير من القدرة على البرنامج، وبعد كل ما يمكنك من الممكن القيام به إذا ما ألقيت VirtualError أخطاء أخرى. ليس كثيرا باستثناء السجل ومتابعة.
وجميع الاستثناءات هي مشكلة في النهاية ... ويقول أيضا أخطاء هي البق لا يعني أي شيء.
وأخطاء ليست البق - فهي المشاكل التي المضيف VM تشهد، على سبيل المثال OutOfMemoryError. الاستثناءات هي وسيلة أن العملية الحالية قد تستخدم لإعلام أنه فشل وربما توفير بعض التشخيص.
وعموما، فإنك لن رمي أو قبض قابل للظهور. على وجه الخصوص، أخطاء JVM (التي تمتد خطأ ()) لا <م> يعني م> أن تكون اشتعلت من قبل رمز المستخدم إلا إذا كنت تقوم بعمل غريب على مستوى النظام.
وعلاج "قابل للظهور" باعتباره الأداة اللغوية. يدعى الطبقة "استثناء" التي لأنه هو الذي يهدف إلى استخدامها من قبل المبرمجين عندما يريدون كتلة التعليمات البرمجية للخروج "استثنائي" - التي لا تخرج عادة أو إرجاع قيمة
وهذا يشمل كلا من حالات الخطأ العادية (عن طريق "العادية" أعني على العكس من الأخطاء JVM) والأماكن التي تستخدم استثناءات كآلية السيطرة.
لا يجب عليك استخدام الاستثناءات كـ "نوع إرجاع" أيضًا ...
إذا كان الشرط الذي تطرحه شائعًا، فأنت تنفق قدرًا كبيرًا من الموارد لإعادة هذا الشرط إلى روتين الاستدعاء.الاستثناءات مكلفة للبناء.
لقد رأيت حالات حيث ألقت الحلقات الضيقة الاستثناءات باعتبارها "سلبية" على سبيل المثال.تخصيص المعرف، هذا الروتين يشغل حوالي 99% من وقت وحدة المعالجة المركزية.وعندما تم تغييره إلى ثابت إرجاع موثق بدلاً من ذلك، انخفض هذا إلى 25%.